es6 强制开启严格模式 es5 开启严格模式要添加 “use strict”
let
{
// 不属于顶层对象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
{
// 不属于顶层对象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对象中要是有属性是对象,该对象内属性还能改变,要全不可变,就需要使用递归等方式一层一层全部冻结。