说明:第一次写作,部分内容的出处已经无法查找,对提供帮助的大佬表示感谢。
使用let语句,允许你在JavaScript中创建块范围局部变量。let语句是在JavaScript的 ECMASript 6标准中引入的。
关于let的使用要注意如下几点:
首先look look什么是变量提升。JavaScript 中,函数及变量的声明都将被提升到函数的最顶部,变量可以在使用后声明,也就是变量可以先使用再声明。
用var声明的变量是存在变量提升的,看一个栗子:
function getValue(condition) {
console.log(value);
if(condition){
var value = "blue"
return value;
} else {
console.log(value)
return null
}
}
看一下给condition传入true和false之后的调用结果:
getValue(true);
//undefined
getValue(false);
//undefined
//undefined
代码没有报错,而是输出value的值为undefined。这是因为value的声明被提到了函数的最顶部,相当于如下的代码:
function getValue(condition) {
var value;
console.log(value);
if(condition){
value = "blue"
return value;
} else {
console.log(value)
return null
}
}
在JS中一个已经声明但没有赋值的变量的值是undefined。所以传参为true的时候输出一次undefined,传参为false的时候输出两次undefined。
下面看一下,如果我们将var改为let来声明value的情况:
function getValue(condition) {
console.log(value);
if(condition) {
let value = "blue";
return value;
} else {
console.log(value);
return null;
}
}
getValue(true)
//Uncaught ReferenceError: value is not define at getValue
我们看到了,用let声明的变量是不存在变量提升的,所以使用的时候要注意啦,先声明再使用!
至此,我们知道了:let声明的变量是不会提升的。在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ) 。
还是先看一下使用var重复声明变量的情况:
var count = 30;
var count = 40;
console.log(count);//40
可以看到使用var关键字,可以使用相同名称声明多个变量,完全没问题,没有报错。这也是为什么早期使用var声明变量的时候会造成覆盖和名字冲突的原因。
在看看使用ES6的let声明同名变量的情况:
let count = 30;
let count = 40;
我们发现,这样做的话,在编辑器中编译不会通过并且浏览器会报错。
说到了作用域,这可是一个大话题,以后再专门说说作用域。在ES6没有诞生之前,JS有全局作用域、函数作用域,但是没有块级作用域。ES6中新增了块级作用域。
本小节的标题是“let声明的变量只在块级作用域内有效”,这有什么可说的呢?我们谈谈块级作用域有什么优势?为什么需要块级作用域?
这就要扯到了ES5在没有块级作用域时出现了哪些问题?先来看代码:
var funcs = [];
for(var i=0;i<10;i++) {
funcs.push(function(){
console.log(i);
})
}
funcs.forEach(function(func){
func();
})
猜猜这一小段代码的会输出什么?有经验的都知道哦!会输出10次10,并不是我们期望的0-9。
为什么是这样的?因为i是使用var声明的全局变量,在全局作用域内有效,循环结束后它的值会变为10。而funcs中的每一个函数的console.log()语句引用的是同一个i,所以值都为10。
怎么解这个问题呢?ES5中的一种方案是利用IIFE(立即调用函数表达式),看代码:
var funcs = [];
for(var i=0;i<10;i++) {
funcs.push((function(value){
return function(){
console.log(value);
}
}(i)));
}
funcs.forEach(func => {
func();
})
这回funcs数组中每次push进去的是一个IIFE,每次循环时i作为参数传给形参value,这样就能够保持对此值的引用,可以达到我们想要的结果:
好麻烦,好多括号,懵了... 好了,看一下用let解决能有多香~
var funcs = [];
for(let i=0;i<10;i++) {
funcs.push(function(){
console.log(i);
})
}
funcs.forEach(func => {
func();
})
注意代码中的循环变量i使用了let进行声明,let声明的变量只在块级作用内有效,for循环的时候每一次i都是一个新值。说的直白些,每次循环let声明都会创建一个新变量i,并将其赋值为i的当前值。
嗯~,有关let的内容,我们简单的重温到这里,接下来看几道和let有关的面试题检测一下知识的掌握情况吧~
1.下面代码的输出是什么?
2.下面代码的输出是什么?
好了,这就是本次的全部内容了。如有错误,请不吝指正。温故而知新,欢迎和我一起重温旧知识,攀登新台阶~
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- esig.cn 版权所有 湘ICP备2023023988号-3
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务