ES6之前JavaScript没有块级作用域,它使用var
声明变量,以function来划分作用域,大括号“{}” 却限定不了var
的作用域,用var
声明的变量具有变量提升(declaration hoisting)的效果。ES6新增加了一个let
,可以在{}, if
, for
里声明。用法同var
,但作用域限定在块级,let
声明的变量不存在变量提升。
例1: 块级作用域 if
function test(flag) { if (flag) { var a = 'js' } // 这里也可以访问 a }
变量a在if
块里声明的,但在else
块和if
外都可以访问到val
,把var
换成let
后:
function test(flag) { if (flag) { let a = 'js' } // 这里也访问不到 a }
例2块级作用域 for
for(var i=0; i<2; i++){ console.log('outer i: ' + i); for(var i=0; i<2; i++){ console.log('inner i: '+i); } } //执行结果如下: //outer i: 0 //test.html:12 inner i: 0 //test.html:12 inner i: 1
可以看到,外层循环被打断了,因为i
为全局变量所以 i
的值被内层循环修改了,把内层循环的var
换成let
后:
for(var i=0; i<2; i++){ console.log('outer i: ' + i); for(let i=0; i<2; i++){ console.log('inner i: '+i); } } // 执行结果如下: // outer i: 0 // test.html:12 inner i: 0 // test.html:12 inner i: 1 // test.html:10 outer i: 1 // test.html:12 inner i: 0 // test.html:12 inner i: 1
示例3: 变量提升
先使用后声明
console.log(a) // undefined var a;
变量val
先使用后声明,输出undefined
,也不报错。把var
换成let
,就报错了
console.log(a) // Uncaught ReferenceError: a is not defined let a;
先判断后声明
if (typeof a == 'undefined') { // ... } var a = ''
把var换成let,if处报语法错 Uncaught ReferenceError: a is not defined
if (typeof a == 'undefined') { // ... } let a = ''
ES6规定,如果代码块中存在let
,这个区块从一开始就形成了封闭作用域,凡是在声明之前就使用,就会报错。即在代码块内,在let
声明之前使用变量都是不可用的。
最新评论
写的挺好的
有没有兴趣翻译 impatient js? https://exploringjs.com/impatient-js/index.html
Flexbox playground is so great!
感谢总结。
awesome!
这个好像很早就看到类似的文章了
比其他的教程好太多了
柯理化讲的好模糊…没懂