ES6新增声明关键字
在ES5中,变量声明只有var 和function以及隐式声明三种,而ES6中新增了let和const 。
- let声明变量
1.let声明的变量不会挂在window中,不会造成全局变量的污染
for (let i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
//当前的i仅在本轮的循环中有效,就是说每一次循环,i其实都是一个新产生的变量。
//用 let 声明的变量 i 只作用于循环体内部,不受外界干扰。
}, 0);
}
// 输出结果:0 1 2 3 4 5 6 7 8 9
//这时在全局console.log(i),结果报错
2.新增了一个块级作用域{},以前只有函数作用域,全局作用域
let声明的变量的作用域是块级作用域,在ES5 并没有块级作用域,只有函数作用域和全局作用域。
for (var i = 0; i <10; i++) {
setTimeout(function() { // 同步注册回调函数到异步的宏任务队列。
console.log(i); // 执行此代码时,同步代码for循环已经执行完成
}, 0);
}
// 输出结果:10个10
// 这里变量为i的for循环中,i是一个全局变量,在全局范围内都有效,
3.let是不允许重复声明
//在相同的作用域内,用let声明变量时,只允许声明一遍,但 var是可以多次声明的。
//1.var声明的变量可多次声明,只是会覆盖
function fun() {
var a = '123';
var a = '456';// 不会报错,会覆盖,此时ad等于456
}
//2.let声明的变量不允许多次声明,会报错
function fun() {
let a = '123';
let a = '456';// 报错
}
//3.开始用let声明过的变量后面也不会允许再用其他的关键字声明
function fun() {
let a = '123';
var a = '456';// 报错
}
4.let不会有声明提前(只是人为看到的效果,实际上是有声明提前,提前临时性的死区中:Cannot access ‘num’ before initialization),也就是变量定于在哪里,就从哪里开始可以使用。提前使用就会报临时性的死区的错误。
- const声明常量
const的特性与let基本一致:块级作用域、暂时性死区、不能重复声明,没有变量提升等。
不同的是
- const是用来定义常量;
- const声明的常量的值,必须在声明的时候赋值,并且赋值后不能修改;
- 特殊情况,当声明的常量是一个对象时:
那么对于对象本身是不允许重新赋值的,但是对于对象的属性是可以重新赋值的。
const obj = {};
obj.name = 'xxx';
console.log(obj.name); //'xxx'
ps:
1.实际上const能保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
对于像数值、字符串、布尔值的简单数据类型,值就保存在变量指向的那个内存地址,因此等同于常量。
但对于像对象、数组这样的复合类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针。
2.要彻底将对象或数组冻结,让其属性也不可修改,可使用Object.freeze(obj)方法。
const obj = {
prop: 10
};
Object.freeze(obj);
obj.prop = 33;// error
console.log(obj.prop);//10