您好,欢迎来到世旅网。
搜索
您的当前位置:首页重温JavaScript(lesson1): 关于ES6中的let

重温JavaScript(lesson1): 关于ES6中的let

来源:世旅网

说明:第一次写作,部分内容的出处已经无法查找,对提供帮助的大佬表示感谢。

使用let语句,允许你在JavaScript中创建块范围局部变量。let语句是在JavaScript的  ECMASript 6标准中引入的。

关于let的使用要注意如下几点:

1.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声明的变量是不存在变量提升的,所以使用的时候要注意啦,先声明再使用!

2.暂时性死区(TDZ)的概念

至此,我们知道了:let声明的变量是不会提升的。在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ) 。

3.let禁止重复声明

还是先看一下使用var重复声明变量的情况:

var count = 30;
var count = 40;
console.log(count);//40

可以看到使用var关键字,可以使用相同名称声明多个变量,完全没问题,没有报错。这也是为什么早期使用var声明变量的时候会造成覆盖和名字冲突的原因。

在看看使用ES6的let声明同名变量的情况:

let count = 30;
let count = 40;

我们发现,这样做的话,在编辑器中编译不会通过并且浏览器会报错。

4.let声明的变量只在块级作用域内有效

 

说到了作用域,这可是一个大话题,以后再专门说说作用域。在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有关的面试题检测一下知识的掌握情况吧~

5.和let相关的几个面试题

1.下面代码的输出是什么?

2.下面代码的输出是什么?

好了,这就是本次的全部内容了。如有错误,请不吝指正。温故而知新,欢迎和我一起重温旧知识,攀登新台阶~

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- esig.cn 版权所有 湘ICP备2023023988号-3

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务