es6 强制开启严格模式 es5 开启严格模式要添加 “use strict”

let

  1. {
  2. // 不属于顶层对象window
  3. // 不允许重复声明
  4. // 不存在变量提升
  5. // 暂时性死区
  6. // 块级作用域
  7. // let不允许在相同作用域内重复声明同一个变量,即同一个作用域内不允许出现名称相同的变量。
  8. let a = 1;
  9. let a = 2; // Identifier 'a' has already been declared
  10. console.log(a); // 1
  11. console.log(b); // undefined
  12. var b = 5;
  13. // 等同于
  14. // var b
  15. // console.log(b)
  16. // b = 5;
  17. for (var i = 0; i < 3; i++) {
  18. (function (j) {
  19. setTimeout(function () {
  20. console.log(j);
  21. });
  22. })(i);
  23. }
  24. for (let i = 0; i < 3; i++) {
  25. setTimeout(function () {
  26. console.log(i);
  27. });
  28. }
  29. // let声明的变量只在它所在的代码块有效。
  30. // for循环的计数器,就很合适使用let命令
  31. for (let i = 0; i < 10; i++) {
  32. // ...
  33. }
  34. console.log(i);
  35. // ReferenceError: i is not defined
  36. // 计数器i只在for循环体内有效,在循环体外引用就会报错。
  37. }

const

  1. {
  2. // 不属于顶层对象window
  3. // 不允许重复声明
  4. // 不存在变量提升
  5. // 暂时性死区
  6. // 块级作用域
  7. // const用于声明常量,一旦声明,必须立即赋值,且以后不可更改。
  8. // 使用const声明对象的时候,只能保证对象的引用地址不被更改,并非此对象不被修改。
  9. const PI = 3.1415926;
  10. PI; // 3.1415926
  11. PI = 3; // TypeError: Assignment to constant variable.
  12. // 解释:这里的k为对象的时候,对象是引用类型,这里的返回值是对象的指针,k是指向这个对象存储的这个指针,这个指针是不变的,但是,对象本身是可以变的
  13. const k = {
  14. a: 1
  15. };
  16. k.b = 3;
  17. console.log(PI, k); // 3.1415926 {a: 1, b: 3}
  18. }

var,let和const之间的区别

变量提升方面

var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined。 let和const不存在变量提升问题(注意这个‘问题’后缀,其实是有提升的,只不过是let和const具有一个暂时性死区的概念,即没有到其赋值时,之前就不能用),即它们所声明的变量一定要在声明后使用,否则报错。

块级作用域方面

var不存在块级作用域,let和const存在块级作用域

声明方面

var允许重复声明变量,let和const在同一作用域不允许重复声明变量。其中const声明一个只读的常量(因为如此,其声明时就一定要赋值,不然报错)。一旦声明,常量的值就不能改变。

如何使const声明的对象内属性不可变,只可读呢?

如果const声明了一个对象,对象里的属性是可以改变的。 因为const声明的obj只是保存着其对象的引用地址,只要地址不变,就不会出错。

使用Object.freeze(obj) 冻结obj,就能使其内的属性不可变,但它有局限,就是obj对象中要是有属性是对象,该对象内属性还能改变,要全不可变,就需要使用递归等方式一层一层全部冻结。