块级作用域
ES6新增了let命令,用来声明局部变量,let声明的变量,只在let所在的代码块(大括号)中有效,所以let真正实现了块级作用域
{
let a = 1;
var b = 2'
}
a // ReferenceError: a is not defined
b // 2
这样,创造块级作用域的立即执行的函数(IIFE)就不需要了
// ES5
(function(){
var a = 1;
})()
// ES6
{
let a = 1;
}
for循环中
for循环关于闭包的坑相信大家都踩过
var arr = [];
for(var i = 0; i < 3; i++){
arr[i] = function(){
console.log(i);
}
}
arr[0]() // 3
当调用arr[i]函数时,因为函数内部没有定义i,所以函数内部的i拿到是外部的i,也就是闭包。然而由于var i的声明在全局都有效,所以每次循环,i的值就被重写,请看以下代码
var i = 5;
for(var i = 0; i < 2; i++){
...
}
i // 已经被重写成了2
所以如果在有一个在循环作用域内的变量就能解决这个问题
var arr = [];
for(let i = 0; i < 3; i++){
arr[i] = function(){
console.log(i);
}
}
arr[0]() // 0
再也不需要再使用这样的代码:
var arr = [];
for(var i = 0; i < 3; i++){
(function(i){
arr[i] = function(){
console.log(i);
}
})(i)
}
arr[0]() // 0
不存在变量提升
var命令会发生变量提升现象,在声明前使用值为undefined
console.log(a); // undefined
var a = 5;
let声明的变量一定要在声明后使用,否则会报错
console.log(a); // ReferenceError
let a = 5;
连最安全的typeof都会报错
typeof a; // ReferenceError
let a = 5;
不允许重复声明
不允许在同一个作用域内重复声明一个变量,这点和ES6的关键字class以及const一样
let a = 1;
//不同作用域,重复声明没有关系
function b(){
let a = 2;
}
相同作用域下
function b(){
let a = 1;
let a = 2; //Identifier 'a' has already been declared
}
const
const声明一个只读的常量。一旦声明,常量的值就不能改变,所以在声明const的时候一定要赋值
const a; //报错
改变const的值也会报错
const a = 1;
a = 5; //报错
const的作用域与let相同,只在声明所在的块级作用域内有效,同样也不存在变量提升,所以const是只读的let