let与var的区别
来源:互联网 发布:c专家编程pdf 非扫描 编辑:程序博客网 时间:2024/04/29 22:13
let
语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
语法
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
参数
var1
,var2
, …,varN
- 变量名。可以是任意合法的标识符。
value1
,value2
, …,valueN
- 变量的初始值。可以是任意合法的表达式。
描述
let
允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是,它声明的变量只能是全局或者整个函数块的。
这里解释了我们为什么选取“let”这个名字。
作用域规则
let
声明的变量只在其声明的块或子块中可用,这一点,与var
相似。二者之间最主要的区别在于var
声明的变量的作用域是整个封闭函数。
function varTest() { var x = 1; if (true) { var x = 2; // 同样的变量! console.log(x); // 2 } console.log(x); // 2}function letTest() { let x = 1; if (true) { let x = 2; // 不同的变量 console.log(x); // 2 } console.log(x); // 1}
简化内部函数代码
当用到内部函数的时候,let
会让你的代码更加简洁。
var list = document.getElementById('list');for (let i = 1; i <= 5; i++) { let item = document.createElement('li'); item.appendChild(document.createTextNode('Item ' + i)); item.onclick = function(ev) { console.log('Item ' + i + ' is clicked.'); }; list.appendChild(item);}// to achieve the same effect with 'var'// you have to create a different context// using a closure to preserve the valuefor (var i = 1; i <= 5; i++) { var item = document.createElement('li'); item.appendChild(document.createTextNode('Item ' + i)); (function(i){ item.onclick = function(ev) { console.log('Item ' + i + ' is clicked.'); }; })(i); list.appendChild(item);}
以上示例的工作原理是因为(匿名)内部函数的五个实例引用了变量i
的五个不同实例。注意,如果你将let
替换为var
,则它将无法正常工作,因为所有内部函数都将返回相同的i
:6的最终值。此外,我们可以通过将创建新元素的代码移动到每个循环的作用域来保持循环更清晰。
在程序或者函数的顶层,let
并不会像var
一样在全局对象上创造一个属性,比如:
var x = 'global';let y = 'global';console.log(this.x); // "global"console.log(this.y); // undefined
模仿私有接口
在处理构造函数的时候,可以通过let
绑定来共享一个或多个私有成员,而不使用闭包:
var Thing;{ let privateScope = new WeakMap(); let counter = 0; Thing = function() { this.someProperty = 'foo'; privateScope.set(this, { hidden: ++counter, }); }; Thing.prototype.showPublic = function() { return this.someProperty; }; Thing.prototype.showPrivate = function() { return privateScope.get(this).hidden; };}console.log(typeof privateScope);// "undefined"var thing = new Thing();console.log(thing);// Thing {someProperty: "foo"}thing.showPublic();// "foo"thing.showPrivate();// 1
let
暂存死区的错误
在相同的函数或块作用域内重新声明同一个变量会引发SyntaxError
。
if (x) { let foo; let foo; // TypeError thrown.}
在 ECMAScript 2015 中,let
绑定不受变量提升的约束,这意味着let
声明不会被提升到当前执行上下文的顶部。在块中的变量初始化之前,引用它将会导致ReferenceError
(而使用 var 声明变量则恰恰相反,该变量的值是 undefined )。该变量处于从块开始到初始化处理的“暂存死区”。
function do_something() { console.log(bar); // undefined console.log(foo); // ReferenceError: foo is not defined var bar = 1; let foo = 2;}
在 switch
声明中你可能会遇到这样的错误,因为它只有一个块.
switch (x) { case 0: let foo; break; case 1: let foo; // TypeError for redeclaration. break;}
但是,重要的是要指出嵌套在case子句内的块将创建一个新的块作用域的词法环境,这不会产生上面显示的重新声明错误。
let x = 1;switch(x) { case 0: { let foo; break; } case 1: { let foo; break; }}
与词法作用域结合的暂存死区
由于词法作用域,表达式(foo + 55)
内的标识符“foo”会解析为if块的foo,而不是覆盖值为33的foo。在这一行中,if块的“foo”已经在词法环境中创建,但尚未达到(并终止)其初始化(这是语句本身的一部分):它仍处于暂存死区。
function test(){ var foo = 33; if (true) { let foo = (foo + 55); // ReferenceError }}test();
这种现象可能会使您陷入以下情况。指令let n of n.a
已经在for循环块的私有范围内,因此标识符“n.a”被解析为位于指令本身的第一部分(“let n”)中的'n'对象的属性'a' ,由于尚未达成和终止其声明,因此仍处于暂存死区。
function go(n) { // n here is defined! console.log(n); // Object {a: [1,2,3]} for (let n of n.a) { // ReferenceError console.log(n); }}go({a: [1, 2, 3]});
其他情况
当在块中使用时,let
将变量的作用域限制为该块。注意var
的作用域在它被声明的函数内的区别。
var a = 1;var b = 2;if (a === 1) { var a = 11; // the scope is global let b = 22; // the scope is inside the if-block console.log(a); // 11 console.log(b); // 22} console.log(a); // 11console.log(b); // 2
- var 与 let 的区别
- let与var的区别
- ECMAScript中let与var的区别
- ES6----var与let的区别
- ES6中let与var的区别
- var与let,const区别
- var和let的区别
- let、var、const的区别
- let和var的区别
- let const var 的区别
- var与const与let之间的区别
- javascript中var与let与const的区别
- ES6 中的let、const与var的区别
- ES5中的var与ES6中的let,const的区别
- 【JavaScript】let与var的区别及变量、函数提升
- ES6中let与var区别
- ES6 let、var、const联系与区别
- swift中let 和var的区别
- Mongodb集群节点故障恢复场景分析
- tablayout 设置下划线宽度。
- tensorflow安装、tensorboard使用
- 利用eclipse新建的java web项目没有web.xml文件怎么办?
- 初学QML之qmlRegisterType
- let与var的区别
- Xcode调试方法总结
- 使用QT点击运行按钮无任何反应,出现错误Could not create directory
- Openstack api 学习文档 & restclient使用文档
- (学习中)Tensorflow tower
- react-native-qiniu源码修改
- Tomcat共享ServletContext
- CodeForces Gym 101630简要题解
- 有没有大神来帮忙看一下