es6 强制开启严格模式 es5 开启严格模式要添加 “use strict”
let
{// 不属于顶层对象window// 不允许重复声明// 不存在变量提升// 暂时性死区// 块级作用域// let不允许在相同作用域内重复声明同一个变量,即同一个作用域内不允许出现名称相同的变量。let a = 1;let a = 2; // Identifier 'a' has already been declaredconsole.log(a); // 1console.log(b); // undefinedvar 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
{// 不属于顶层对象window// 不允许重复声明// 不存在变量提升// 暂时性死区// 块级作用域// const用于声明常量,一旦声明,必须立即赋值,且以后不可更改。// 使用const声明对象的时候,只能保证对象的引用地址不被更改,并非此对象不被修改。const PI = 3.1415926;PI; // 3.1415926PI = 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对象中要是有属性是对象,该对象内属性还能改变,要全不可变,就需要使用递归等方式一层一层全部冻结。
