我们都知道var有变量提升的阶段,而let没有,并且let创建的变量有块级私有作用域
还是看实例吧
(1)
if('m' in window){
var m=m && 12;
}
console.log(m);
输出结果是undefined,和你预期想的一样吗?
知识点:首先,基于var声明全局变量,也相当于给window设置了一个属性;
其次,var存在变量提升,那么就相当于在window下已经声明了m,但并未赋值,所以是undefined
最后,m= m && 12= undefined && 12= undefined
补:(与运算:左为真,返回右边;左为假,返回左边)
重:var创建变量时,第一步是声明一个变量,第二步是在堆内存中创建一个值,第三步是把声明的变量与这个值连接起来。
再来看一个
(2)
let n=10;
if(!(n in window)){
let n=n+30;
}
这段代码运行时会报错,Cannot access 'n' before initialization
原因(重):let创建变量时,第一步先准备值,第二步声明变量,第三步把值与变量连起来。
在方法体内,在执行第一步的时候创建n+30,此时块级作用域的n就没有声明,所以如上报错。
(补) 词法分析:let n
1)当前变量n是块级作用域的私有变量
2)n是基于ES6创建的,不会变量提升
你可能恍然大悟,别急,再来看下一道。
(3)
let n=10;
if(!(n in window)){
let m=n+30;
}
console.log(n);
细心一点会发现,这道题就是把上一道题中的let n=n+30改成了let m=n+30;没错就是这细微的改变结果截然不同。
结果:10
为什么会这样呢?我想这个问题想了一阵,我总觉得结果应该和上一个一样啊,最后终于通了!
原因:对于m=n+30,当创建n+30时,由于if方法体内没有创建n(没有let n),所以不形成私有块级作用域,n继承上边的,n=10,m=n+30=10+30=40;所以不报错,并且最终输出n=10
我今天是get到了,原来自己之前都是知其然,但不知其所以然啊~