你已处于离线状态,显示的是缓存的页面内容

ES6语法学习day2之暂时性死区

时间:2026-07-02   标签: ES6, 语法, 分享

暂时性死区第二关

if (true) {
  // TDZ开始
  tmp = "abc"; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

效果

PS C:\Users\Admin\Documents\node-learn> node .\7.js
C:\Users\Admin\Documents\node-learn\7.js:3
  tmp = "abc"; // ReferenceError
      ^

ReferenceError: Cannot access 'tmp' before initialization
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\7.js:3:7)
    at Module._compile (node:internal/modules/cjs/loader:1812:14)
    at Object..js (node:internal/modules/cjs/loader:1943:10)
    at Module.load (node:internal/modules/cjs/loader:1533:32)
    at Module._load (node:internal/modules/cjs/loader:1335:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
    at node:internal/main/run_main_module:33:47

Node.js v24.14.1

这个案例可以看出,在没有声明之前赋值,会直接抛出 ReferenceError

暂时性死区的 typeof

在暂时性死区下 typeof 将不再是百分百安全的操作

typeof x; // ReferenceError
let x;

//typeof x;

效果

PS C:\Users\Admin\Documents\node-learn> node .\8.js
C:\Users\Admin\Documents\node-learn\8.js:1
typeof x; // ReferenceError
^

ReferenceError: Cannot access 'x' before initialization
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\8.js:1:1)
    at Module._compile (node:internal/modules/cjs/loader:1812:14)
    at Object..js (node:internal/modules/cjs/loader:1943:10)
    at Module.load (node:internal/modules/cjs/loader:1533:32)oader:1335:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
    at node:internal/main/run_main_module:33:47

Node.js v24.14.1

let x 之前,都属于 x 的死区

与之相反,代码中如果没有 let x ,就不存在 x 的死区

// typeof x; // ReferenceError
// let x;

typeof x;

效果

PS C:\Users\Admin\Documents\node-learn> node .\8.js

隐蔽的死区

有些死区也比较隐蔽

function bar(x = y, y = 2) {
  // 参数默认值形成独立作用域,x 的默认值表达式引用 y
  // x 的初始化在 y 之前(参数从左到右求值),此时 y 尚未初始化,处于 TDZ
  return [x, y]; // 因报错不会执行到这
} // 函数定义无问题,但调用时会触发 TDZ
bar(); // 调用时,x 尝试取 y 的值,y 在作用域内但未初始化,抛出 ReferenceError
// 报错原因:参数 y 在 x 的右侧,默认值求值时 y 不可访问(死区)
PS C:\Users\Admin\Documents\node-learn> node .\9.js
C:\Users\Admin\Documents\node-learn\9.js:1
function bar(x = y, y = 2) {
                 ^

ReferenceError: Cannot access 'y' before initialization
    at bar (C:\Users\Admin\Documents\node-learn\9.js:1:18)
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\9.js:5:1)
    at Module._compile (node:internal/modules/cjs/loader:1812:14)
    at Object..js (node:internal/modules/cjs/loader:1943:10)
    at Module.load (node:internal/modules/cjs/loader:1533:32)
    at Module._load (node:internal/modules/cjs/loader:1335:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
    at node:internal/main/run_main_module:33:47

Node.js v24.14.1

正确写法

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

输出

PS C:\Users\Admin\Documents\node-learn> node .\10.js

如果你想让代码返回 bar() 的值,则把 bar() 改成 console.log(bar()),即

function bar(x = 2, y = x) {
  return [x, y];
}
console.log(bar()); // [2, 2]

结果

PS C:\Users\Admin\Documents\node-lear
n> node .\10.js
[ 2, 2 ]

letvar行为不同

// 不报错
var x = x;

// 报错
let x = x; // 这里把 x 赋值给 x 相当于 x 还没声明就去取 x 的值
// ReferenceError: x is not defined

效果

PS C:\Users\Admin\Documents\node-learn> node .\11.js
C:\Users\Admin\Documents\node-learn\11.js:5
let x = x;
    ^

SyntaxError: Identifier 'x' has already been declared
    at wrapSafe (node:internal/modules/cjs/loader:1743:18)
    at Module._compile (node:internal/modules/cjs/loader:1786:20)
    at Object..js (node:internal/modules/cjs/loader:1943:10)
    at Module.load (node:internal/modules/cjs/loader:1533:32)
    at Module._load (node:internal/modules/cjs/loader:1335:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
    at node:internal/main/run_main_module:33:47

Node.js v24.14.1

总之

总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量



相关文章

社交的

bilibiliemailYouTube