{
var foo='foo'; let bar='bar'; } console.log(foo,'var'); //foo var
console.log(bar ,'bar');//Uncaught ReferenceError: bar is not defined
在代码中,使用var申明的变量在代码块外面能被识别,可是let命令却不能被识别,这样就实现了js的块级做用域,咱们在使用条件语句 循环语句等就会不担忧变量污染的问题了,如下是两种写法等对比:javascript
es6:java
for (let i = 0; i < a.length; i++) { let x = a[i] … } for (let i = 0; i < b.length; i++) { let y = b[i] … } let callbacks = [] for (let i = 0; i <= 2; i++) { callbacks[i] = function () { return i * 2 } } callbacks[0]() === 0 callbacks[1]() === 2 callbacks[2]() === 4
es5:es6
var i, x, y; for (i = 0; i < a.length; i++) { x = a[i]; … } for (i = 0; i < b.length; i++) { y = b[i]; … } var callbacks = []; for (var i = 0; i <= 2; i++) { (function (i) { callbacks[i] = function() { return i * 2; }; })(i); } callbacks[0]() === 0; callbacks[1]() === 2; callbacks[2]() === 4;
在{}用let声明的变量只有在{}内是有效的 函数
熟悉js开发的都知道函数有两种声明方式es5
a(); // 'a' b(); // 报错不是一个函数 实际上是undefined
function a(){ console.log('a'); } var b=function(){ console.log('b'); }
这两种方式js解析顺序是不同的, 首先函数a会被js加载而后执行 var b ;至于b是什么数据会等第二批执行,也就是正常按照从上到下执行代码,在执行b()的时候仍是未初始化的状态可是并无报错由于var已经被优先执行了 这种就是变量提高,此时咱们修改下代码spa
a(); // 'a' b(); // b is not defined function a(){ console.log('a'); } let b=function(){ console.log('b'); }
虽然还是报错可是明显提示不存在b变量了,因此使用了let以后就不会优先执行了也会回归“第二批”执行的队伍中,function a(){} 依然是“第一批”优先执行的代码。blog
js是存在做用域链的,在特定做用域下只能获取同级或者高层级的变量;可是let存在变量绑定行为,不遵循做用域链;ip
let a=1; (function (){ a=2; //a is not defined let a; console.log(a); }()); let a=1; (function (){ a=2; console.log(a); //2 }());
咱们能够这样理解,在当前执行的做用域内若是没有对变量定义 则会从高层级级获取,若是已经存在则封闭当前做用域再也不考虑高层级是否声明了该变量;作用域
在相同做用域内,let是不能重复声明同一个变量的;可是var则不在意声明多少次,永远都是后者替换前者;开发
var foo=123; var foo=456; console.log(foo); //456 let bar=123; let bar=456; //Identifier 'bar' has already been declared console.log(bar);
有了块级做用域咱们不再用写匿名函数来进行做用域封闭了,之前你多是这样写:
(function () { var foo = function () { return 1; } foo() === 1; (function () { var foo = function () { return 2; } foo() === 2; })(); foo() === 1; })();
可是如今不用这样麻烦了,你彻底能够这样写:
{ function foo () { return 1 } foo() === 1 { function foo () { return 2 } foo() === 2 } foo() === 1 }
参考了了阮一峰的介绍 作了一些简化和本身的例子 欢迎补充~