var/let/const的区别

不使用关键字定义

  • 对于属性进行赋值,相当于在 window 全局对象上声明一个属性. delete: 只能用来删除对象的属性.
a = 7
delete a 
// res -> true
  • 同时不能将该属性提升,即必须先声明才可使用.

var

  • var 相当于在当前作用域声明变量,并且挂载到 window 顶层对象中.但这也引发了一个问题,如果在 window 中挂载过多的变量, 导致 window 越来越大,造成 污染全局变量.
    let 很好的解决了这个问题

let

let a = 5
console.log(a) // 5
console.log(window.a) // undefined
  • 使用 let 不会将 变量 挂载到 window 对象中.避免 污染全局变量
  • let 不允许重复声明.
var a = 5
let a = 6 // 出现报错: Uncaught SyntaxError: Identifier 'a' has already been declared at <anonymous>:1:1
  • let 不存在变量提升,即未初始化不可使用变量,在这种情况下,可避免资源浪费,变量定义更加清晰
console.log(a)
let a = 5 // 出现报错: Cannot access 'a' before initialization at xxxx
  • 为防止声明之前使用变量, let 还有暂时性死区 的特性
var a = 5
// error: Cannot access 'a' before initialization
if (true) {
      // 必须先定义才能使用, 这里的 a 并不会去查找作用域外声明的 a
      a = 5
      let a = 5 
}
  • let 存在 块级作用域 ,块级作用域必须具有大括号
if (true) let a = 5 // 出现报错 Lexical declaration cannot appear in a single-statement context
// 只在当前作用域有效
for (let j = 0; j < 3; j++){
    console.log(j)
}
console.log(j) //  j is not defined
  • 浏览器不能直接使用 ES6 语法, 使用 let babel 自动将let变量转换为var,并将for循环内的函数生成一个闭包.
// 同步操作
for (var i = 0; i < 3; i++) {
  // setTimeout 异步操作 等到主线程空闲并且时间到 才去执行
  setTimeout(function () {
    console.log(i);
  });
} // 3个3

for (let i = 0; i < 3; i++) {
  setTimeout(function () {
    console.log(i);
  });
} // 0 1 2

const

const一般用作常量的定义,与 let 类似.
不管是 ES5 还是 ES6, 常量存储栈中,对于 Object/Array 栈中存储的是引用地址,真正的值是存在堆内存中, 对于堆中的值我们是可以进行修改的.

//ES5 常量定义
Object.defineProperty(window, 'PI', {
  value: 3.14,
  writable: false // 不可写入
})
PI = 6
console.log(PI) // res => 3.14

Object.defineProperty(window, 'MAN', {
  value: {
      name: 'zhangsna',
      age: 5
  },
  writable: false // 不可写入
})
MAN.age = 25
console.log(MAN) // res => {name: "zhangsna", age: 25}

// ES6 常量定义
const a = 5
a = 6
console.log(a) // res => 6

const b = {
      name: 'zhangsan',
      age: 6
}
b.age = 36
console.log(b) // res => {name: "zhangsan", age: 36}
原文地址:https://www.cnblogs.com/pamela1226/p/13204077.html