美文网首页
块级作用域和暂存性死区

块级作用域和暂存性死区

作者: wannaBeACat | 来源:发表于2018-04-21 22:21 被阅读0次

1. 块级作用域

在es6以前写代码, 通常二话不说, 先写一段(function(){})()类似这种的匿名自调函数. 但是现在想要让变量不污染全局环境, 可以有更简单的写法.

{
    var a = 1;
    let b = 1;
}
console.log(window.a); // 1
console.log(window.b); // undefined

这是因为在ES6语法中支持块级作用域, 使用{}来声明一个块级作用域.
并且块级作用域可以嵌套, 同时子级可以访问父级的作用域, 但是父级不能访问子级:

{
    let a = 1;
    {
        console.log(a);
        console.log(b); // Uncaught ReferenceError: b is not defined
        {
            let b = 2;
        }
    }

}

值得注意的一点是, if/for循环中()内使用let或者const声明的变量属于后面的{}, 而不是{}外部:

{
    console.log(i); // Uncaught ReferenceError: i is not defined
    for (let i = 0; i < 3; i++) {
        console.log(i);
    }
}

2.暂存性死区

在相同的函数或块作用域内重新声明同一个变量会引发SyntaxError; 在声明变量或常量之前使用它, 会引发ReferenceError. 这就是暂存性死区.
这里主要存在两个坑点:

  1. switch case中case语句的作用域
switch (x) {
  case 0:
    let foo;
    break;
    
  case 1:
    let foo; // TypeError for redeclaration.
    break;
}

会报错是因为switch中只存在一个块级作用域, 改成以下形式可以避免:

let x = 1;

switch(x) {
  case 0: {
    let foo;
    break;
  }  
  case 1: {
    let foo;
    break;
  }
}
  1. 与词法作用域结合的暂存死区
function test(){
   var foo = 33;
   if (true) {
      let foo = (foo + 55); // ReferenceError
   }
}
test();

在if语句中使用了let声明了foo, 因此在(foo+55)中引用的是if块级作用域中的foo, 而不是test函数中的foo; 但是由于if中的foo还没有声明完:

在这一行中,if块的“foo”已经在词法环境中创建,但尚未达到(并终止)其初始化(这是语句本身的一部分)

因此它仍处于暂存死区.
下面的例子也是同样的问题:

function go(n) {
  // n here is defined!
  console.log(n); // Object {a: [1,2,3]}

  for (let n of n.a) { // ReferenceError: n is not defined
    console.log(n);
  }
}

go({a: [1, 2, 3]});

指令let n of n.a已经在for循环块的私有范围内,因此标识符“n.a”被解析为位于指令本身的第一部分(“let n”)中的'n'对象的属性'a' ,由于尚未达成和终止其声明,因此仍处于暂存死区。

相关文章

  • 块级作用域和暂存性死区

    1. 块级作用域 在es6以前写代码, 通常二话不说, 先写一段(function(){})()类似这种的匿名自调...

  • ES6的let命令(二)

    2.暂时性死区 暂时性死区是指只要块级作用域内存在let命令,它所声明的变量就绑定这个作用域,不会受到外部的影响。...

  • let

    使用let的注意事项 1.块级作用域2.同一作用域中不允许重复声明3.暂存死区(Temporal dead zon...

  • let和const

    块级 var 的情况变量提升 暂时性死区 不允许重复声明 global对象 获取函数名 顶层对象属性 块级作用域和...

  • let、const用法

    let 不存在变量提升 暂时性死区 不允许重复声明 块级作用域外层作用域无法读取内层作用域的变量内层作用域可以定义...

  • ES6 let const

    暂时性死区:只要块级作用域内存在let命令,它所声明的变量就绑定这个区域,不再受外部影响。 暂时性死区:let.c...

  • let,const

    let const let 与var的区别块级作用域不存在变量提升(会导致暂时性死区)不允许重复声明 1.块级作用...

  • [转载]var和let/const

    var和let/const的区别 块级作用域 不存在变量提升 暂时性死区 不可重复声明 let、const声明的全...

  • 面试题 -- let与var的区别

    区别 let 可以定义块级作用域变量 let 配合for循环的独特应用 let 没有变量提升和暂时性死区 ES6 ...

  • var let const

    var 可声明前置 let不可声明前置 let不可重复声明 存在块级作用域 IIFE的替换 暂时性死区(TDZ):...

网友评论

      本文标题:块级作用域和暂存性死区

      本文链接:https://www.haomeiwen.com/subject/xmpflftx.html