let与const命令

let和var一样是用来声明变量的。但是,它与var有很大的不同。

使用let声明的变量只在其所在的代码块内有效。

if (true) { var a = 1; }

console.log(a); //1

if (true) { let a = 1; }

console.log(a); 报错

在全局作用域中,使用let声明的变量不会是window对象的属性。

var age = 1;
console.log(window.age) //1
let age = 1;
console.log(window.age) //undefined

let与for循环

for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i)
}
}

arr[0]() //10
arr[9]() //10

由于变量i指向的是同一个,所以for循环结束后,数值变成了10,输出的也就是10

for (let i = 0; i < 10; i++) {
  arr[i] = function () {
  console.log(i)
  }
}

arr[0]() //0
...
arr[9]() //9

当使用了let关键字后,每次循环都会重新创建i,所以输出的是0-9

使用let的时候,for的括号内为父作用域,花括号内子作用域,它们之间相互独立。

for (let i = 0; i < 10; i++) {
  let i = "a";
  console.log(i) //"a"
}

可以看到,两个变量i之间是独立的,互相不影响。

for (let i = 0; i < 10; i++) {
  console.log(i) 报错
  let i = "a";
  console.log(i) //"a"
}

需要注意的是,在作用域内使用一个let声明的变量的时候,必须是在声明之后使用,否则一律报错!
所以可以看到,绝不像var那样,在变量声明之前使用变量会输出undefined,这种现象称之为变量提升。
而let则杜绝了这种现象,告诉我们先声明,后使用,才是好习惯!

console.log(a)//undefined
var a = 1;

console.log(a) //报错
let a = 1;

创建私有作用域

es5:

(function () {

  var a = 1;
  function fn () {}

})()

console.log(a) 报错
fn() 报错

es6:

{
  let a = 1;
  let fn = function () {};
}
console.log(a) 报错
fn() 报错

不过可惜的是es6的方式不能够有返回值。

使用const声明变量

const声明变量的最大特点是,声明的时候必须立即初始化,声明过后不可修改,否则报错!

const name = 1; //正确

const name; //错误

const name = 1; 
name = 2; //错误

const与let声明的变量一样,只在其所在的代码块内有效,没有变量提升,必须先声明,后使用。在全局作用域中声明的变量不属于window对象的属性。
需要注意的是,对于引用类型的值,const只能保证其内存地址不变,因此在对象上进行一些修改是可行的。

const name = {
a : 1
}

name.a = 2;

console.log(name.a) //2

name = {} 错误

如果想要冻结对象,可以使用freeze方法。

const obj = Object.freeze({
  name : 1
})

obj.name = 2 //无效 严格模式下将报错

但如果对象中包含有对象类型的值,那么这个对象内的对象是可变得。

const obj = Object.freeze({
  name : 1,
  arr : [1]
})

obj.arr.push(1)

console.log(obj.arr) //[1,1]

可以使用递归方法彻底冻结对象

let frreezeObj = (obj) => {
  //冻结对象
  Object.freeze(obj);
  //object.keys方法返回obj中所有可枚举的属性的数组,然后对数组进行遍历
  Object.keys(obj).forEach((key, i) => {
    //如果是引用类型的话
    if (typeof obj[key] === 'object') {
      //调用自身,将对象冻结
       frreezeObj(obj[key]);
    }
  })
}

let obj = {
  arr : [1]
}

frreezeObj(obj);

obj.arr.push(1) //报错:对象不可拓展

猜你喜欢

转载自blog.csdn.net/weixin_40606003/article/details/83684573
今日推荐