参考:阮一峰 http://es6.ruanyifeng.com/#docs/let
时间:2018-07-03
es6引入块级作用域
let:声明变量,与var有区别
1.以下介绍会与var进行对比
{ let a=1; var b=2; } console.log(a);//undefined console.log(b);//2
解析:a的作用域是块级作用域,a只在当前的代码块有作用,b是全局,所以显示如此
{ let a=1; var a=2; } console.log(a);//报错
解析:let声明的变量会锁死当前块级作用域,不允许重复声明相同名字的变量,所以在浏览器控制台调试记得加{},避免重复声明
for(let i=1;i<10;i++){ console.log(i) } console.log(i)//i is not defined //如果把let 改成var呢
解析:循环里let 生命的变量,块级作用域子作用域会找到;用var则也是全局变量
var a=[]; for(var i=0;i++;i<10){ a[i]=function(){ console.log(i) } } a[6]();//10 var a=[]; for(let i=0;i++;i<10){ a[i]=function(){ console.log(i) } } a[6]();//6
解析:var 在循环里声明的变量是全局的,js执行完for才会执行后面的语句,a[6]()函数执行时,for早循环完,此时a[6]里保存着指向函数function(){console.log(i)}的地址,a[6]()执行函数,从全局里找到i,此时i为10;
let在循环里声明的变量属于当前块级作用域的,每个i只在当前循环体内有效,而js会记住上一次循环值,初始化本轮,所以尽管a[6]()在for循环后执行,但是它的循环i的值还保留;所以会输出6
console.log(a);//undefined var a=10; console.log(b);//报错 let b=19;
解析:var声明的变量,存在变量提升,即提到最顶部,但赋值留在原地;而let不存在这种情况
2.暂时性死区
在上面有个例子已经说明let声明的变量会锁死当前作用域块,在此基础上进行延伸
{ typeof x;//小写的of,此时会报错,声明之前只要用到锁死区的变量都会报错 let a = 10; } { typeof(hello)//undefined }
{
let x=x//只要在声明完成前使用,就会报错
}
{
let x;
x=x;//undefined,不会报错
}
暂时性死区本质是只要进入当前作用域,变量已经存在,不能获取和使用,只有在声明后才可以。
熟悉下:
{ let n=10; { let n=5; } console.log(n)//10 } { let n = 10; { n=5; } console.log(n)//5 } console.log(n)//n is not defined
3.const
声明赋值,值不可变,同样是块级作用域。
但是js对于引用的变量,只保存它的地址,也就是说只要这个地址不变,地址指向的引用里的值是可以改变的
const foo={}; foo.me='年轻的'; console.log(foo); //////////////////////////// const foo = {}; foo={};//报错,因为值改了,啥?没改,改了,两个空对象不代表引用地址一样。美丽的js
4.es6声明变量的六种方法
var function let const import class
5.let和var还有个区别
let在全局声明,只是全局变量,而var则会是顶层
let a=10; window.a//undefined; var b=10; window.b//10
6.啥?不知道顶层对象?
顶层:浏览器指的是window或者self(你厉害) 但是node顶层是global而Web Worker的是self
具体请参照:http://es6.ruanyifeng.com/#docs/let