基本用法
var a = 1;
let b = 2;
const c = 3;
在for循环中的运用
var a = [];
for (var i = 0; a < 10; i++){
a[i] = function(){
console.log(i);
}
}
a[6]() //10
var a = [];
for (let i = 0; a < 10; i++){
a[i] = function(){
console.log(i);
}
}
a[6]() //6
第一个例子中使用var 生命的,在全局范围内有效,在for循环生成了10个函数,每个函数打印i;i经过for循环后变为了10;所以答应出10来了。第二个例子中,i用let声明,i只在本次循环中使用,每次循环都是一个新的变量i,在循环for()的括号中相当于一个独立的父作用域,而循环体内是一个单独的子作用于。
for(let i = 0; i < 10; i++){
let i = "abc";
console.log(i);
}
//abc
//abc
//abc
内部i与循环中的i不在同一个作用域,各自有单独的作用域
不存在变量提升
console.log(foo); //undefined
var foo = 2;
console.log(bar); //ReferenceError
let bar = 2;
let const在区块中声明,从一开始就生成了封闭区域,只要在声明之前使用就会报错,在声明之前这块区域成为暂时性死区(temporal dead zone),所以在ES6中typeof 一个声明前的变量会报错ReferenceError而不是undefined,要慎用。
不能重复声明变量
let a = 0;
var a = 3;
//Uncaught SyntaxError: Identifier 'a' has already been declared
块级作用域
在{}中声明的let 变量都有其独立的块级作用域,可以很好地替代ES5中的立即执行函数
function fn(){
let n = 5;
if (true) {
let n = 10;
}
console.log(n);
}
fn()//5
const
const 用于声明一个常量,但对于引用类型const保存的事一个指针地址,这个地址是固定不变的。如对于Object与数组是可以改变里面的值,但是不可以重新赋值。
const a = {};
a.prop = "a";
a = {
b: 1
};
//TypeError: Assignment to constant variable.
如果想达到冻结不可变的效果,可以采用 Object.freeze方法
顶层对象
浏览器 =》window对象
node =》 global对象
es5中var 声明的全局变量就等于顶层变量
es6 中let 和const 声明的变量将不再挂在window对象上,全局变量与顶层变量隔离;