ES6—let关键字

目录

一、概述

二、详解

三、拓展


一、概述

        let是ES6新增的关键字,作用是声明变量。

let a; // 单个声明变量
let b, c, d; // 批量声明变量
let e = 100; // 单个声明变量并赋值
let f = 100, g = 200, h = []; // 批量声明并赋值

        使用let声明的变量有如下四个特点。

1)不允许重复声明
2)块级作用域
3)不存在变量提升
4)不影响作用域链

二、详解

不允许重复声明

        如下代码所示,let不允许在相同作用域内,重复声明同一个变量。

let a = 100;
let a = 200;

// 报错:Uncaught SyntaxError: Identifier 'a' has already been declared

块级作用域

        ES5只有两种作用域,分别是全局作用域和函数作用域。ES6新增了块级作用域,let声明的变量只在当前块级作用域内有效。

{
    let dog = "京巴";
    console.log(dog); // 京巴
}
console.log(dog); // 报错:Uncaught ReferenceError: dog is not defined

         不同作用域之间可以定义同名变量。

扫描二维码关注公众号,回复: 15514813 查看本文章
{
    let dog = "京巴";
    {
        let dog = "哈士奇"
        console.log(dog); // 哈士奇
    }
    console.log(dog); // 京巴
}

        块级作用域完全可以替代匿名函数。

// 匿名函数
(function () {
  var dog = "阿拉斯加";
  // ...
}());


// 块级作用域
{
  let dog = "阿拉斯加";
  // ...
}

        如下代码所示,var关键字声明的变量会泄漏为全局变量,这种情况可以使用let关键字代替var声明变量,以避免泄漏。

for (var i = 0; i < 10; i++) {

}
console.log(i) // 10

不存在变量提升

        let关键字声明的变量不存在变量提升。

console.log(a); // 输出undefined
var a = 2;

console.log(bar); // 报错: Uncaught ReferenceError: bar is not defined
let bar = 2;

不影响作用域链

        let关键字声明的变量遵循作用域链的规则,即下级可用上级代码块中的局部变量。

{
    let p = "泰迪";
    {
        console.log(p);
    }
}

三、拓展

块级作用域与函数声明

        ES5规定函数只能在全局作用域和函数作用域中声明,不能在代码块即ES6提出的块级作用域中声明。如下代码所示,根据ES5的规定,是非法的。但浏览器为了兼容以前的旧代码,对于这种非法操作,并没有报错,且能正常执行。

if (true) {
    function func() { }
}

        ES6正式引入块级作用域的概念,明确允许在块级作用域中声明函数,但声明的函数仅作用于当前块级作用域。

        注意,块级作用域中函数声明的具体行为受环境影响较大,应尽量避免在块级作用域中使用函数声明,若必须使用函数,推荐使用函数表达式的形式。

{
    let func = function() { }
}

块级作用域必须有大括号

        如下代码所示,省略大括号后报错,报错信息翻译为"词法声明不能出现在单个语句的上下文中",简单说,就是单行的条件语句中,不允许使用let关键字。

// 报错:Uncaught SyntaxError: Lexical declaration cannot appear in a single-statement context
if (true) let a = 100; 

// 不报错
if (true) {
    let a = 100;
}

暂时性死区

        如下代码所示,let关键字声明的变量绑定在当前块级作用域,全局声明的变量无效,let声明前赋值语句报错。

var a = 123;

if (true) {
  a = 123; // Uncaught ReferenceError: Cannot access 'a' before initialization
  let a;
}

        ES6明确规定,块级作用域对于其内使用let或const命令声明的变量,从一开始就形成了封闭作用域,凡是在声明之前使用这些变量,都会报错,这种现象在语法上叫暂时性死区。如下代码所示,变量a用let声明前,都属于a的死区,无论什么操作,只要用到变量a,就会报错。

{
    console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
    let a;
}

        如下代码所示,是一个比较隐蔽的暂时性死区的例子。

function func(x = y, y = 2) {
  return [x, y];
}

func(); // 报错, y未声明,就将其赋予x

        暂时性死区的本质是,只要一进入块级作用域,所有使用let和const声明的变量就已经存在了,但是不可获取,只有等声明变量的那一行代码出现,才可以获取和使用这些变量。

猜你喜欢

转载自blog.csdn.net/weixin_42472040/article/details/120424105