Skip to content

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

let

javascript
{
  // 不属于顶层对象window
  // 不允许重复声明
  // 不存在变量提升
  // 暂时性死区
  // 块级作用域

  // let不允许在相同作用域内重复声明同一个变量,即同一个作用域内不允许出现名称相同的变量。
  let a = 1
  let a = 2 // Identifier 'a' has already been declared
  console.log(a) // 1

  console.log(b) // undefined
  var b = 5

  // 等同于
  // var b
  // console.log(b)
  // b = 5;

  for (var i = 0; i < 3; i++) {
    ;(function (j) {
      setTimeout(function () {
        console.log(j)
      })
    })(i)
  }

  for (let i = 0; i < 3; i++) {
    setTimeout(function () {
      console.log(i)
    })
  }
  // let声明的变量只在它所在的代码块有效。
  // for循环的计数器,就很合适使用let命令
  for (let i = 0; i < 10; i++) {
    // ...
  }

  console.log(i)
  // ReferenceError: i is not defined
  // 计数器i只在for循环体内有效,在循环体外引用就会报错。
}

const

javascript
{
  // 不属于顶层对象window
  // 不允许重复声明
  // 不存在变量提升
  // 暂时性死区
  // 块级作用域

  // const用于声明常量,一旦声明,必须立即赋值,且以后不可更改。
  // 使用const声明对象的时候,只能保证对象的引用地址不被更改,并非此对象不被修改。
  const PI = 3.1415926
  PI // 3.1415926

  PI = 3 // TypeError: Assignment to constant variable.

  // 解释:这里的k为对象的时候,对象是引用类型,这里的返回值是对象的指针,k是指向这个对象存储的这个指针,这个指针是不变的,但是,对象本身是可以变的
  const k = {
    a: 1,
  }
  k.b = 3
  console.log(PI, k) // 3.1415926 {a: 1, b: 3}
}

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对象中要是有属性是对象,该对象内属性还能改变,要全不可变,就需要使用递归等方式一层一层全部冻结。