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

ES6语法学习之 let

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

准备学习 node.js ,在此之前先学习 ES6 语法

varlet 的区别

  • var:变量声明,全局有效
  • let:竟在所在的代码块生效
{
  var a = 1;
  let b = 2;

  // console.log(a);
}

console.log(a);
console.log(b);

运行效果

PS C:\Users\Admin\Documents\node-learn> node .\let.js
C:\Users\Admin\Documents\node-learn\let.js:8
console.log(a);
            ^

ReferenceError: a is not defined
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\let.js:8:13)
    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

在这段代码里,letlet b = 2 不在一个代码块里,无法调用

正确写法

{
  let a = 1;
  var b = 2;

  console.log(a);
}

// console.log(a);
console.log(b);

运行效果

PS C:\Users\Admin\Documents\node-learn> node .\let.js
1
2

这回成功打印了 let a = 1 的变量 var b = 21 2

forlet

for (let i = 0; i < 10; i++) {
  //   console.log(i);
}

console.log(i);

同样的,for (let i = 0; i < 10; i++)console.log(i); 不在一个代码块里,无法调用

运行结果

PS C:\Users\Admin\Documents\node-learn> node .\for.js
C:\Users\Admin\Documents\node-learn\for.js:5
console.log(i);
            ^

ReferenceError: i is not defined
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\for.js:5:13)
    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

正确写法

for (let i = 0; i < 10; i++) {
  console.log(i);
}

// console.log(i);

运行效果

PS C:\Users\Admin\Documents\node-learn> node .\for.js
0
1
2
3
4
5
6
7
8
9

对比 varletfor 循环中的区别

// 当使用 var 计数器定义是
var a = []; // 声明空数组,用于存储函数
for (var i = 0; i < 10; i++) {
  // var i 为函数级作用域,所有迭代共享同一个 i
  a[i] = function () {
    // 每次循环创建闭包函数,引用外层变量 i(非值拷贝)
    console.log(i); // 函数执行时查找外层 i,此时 i 已是循环结束后的值
  }; // 循环结束后 i 自增为 10,不再满足条件
} // 所有闭包共享同一个 i 变量
a[6](); // 调用索引 6 的函数,输出外层 i 的当前值 10

效果

PS C:\Users\Admin\Documents\node-learn> node .\for1.js
10
// 当使用 let 定义计数器时
var a = []; // 声明空数组
for (let i = 0; i < 10; i++) {
  // let i 为块级作用域,每次迭代独立绑定
  a[i] = function () {
    // 闭包捕获当前迭代的 i(值拷贝)
    console.log(i); // 输出该次迭代的 i 值
  }; // 每个函数保存不同的 i
} // 循环结束,每个 i 绑定依然存在(闭包持有)
a[6](); // 输出 6,因为第 6 次迭代的 i = 6

效果

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

如何在使用 let 定义计数器时,打印 10

// 在使用 let 时让 a 打印 10
var a = []; // 声明空数组
for (let i = 0; i < 10; i++) {
  // let i 每次迭代独立绑定,a[6] 闭包捕获的是 i=6
  a[i] = function () {
    // 定义函数,内部引用当前迭代的 i
    console.log(i); // 输出当前闭包持有的 i(对于 a[6] 输出 6)
    a[6](); // 再次调用自身 → 无限递归,栈溢出(程序崩溃)
  };
}
// a[6]();                         // 若取消注释,会先打印 6,然后无限递归,不会打印 10

for 循环的 父作用域 与 子作用域

for (let i = 0; i < 3; i++) {
  // 外层循环变量 i(数字),块级作用域,每次迭代独立绑定
  let i = "abc"; // 内部块级变量 i(字符串),遮蔽外层的 i,允许重新声明(不同块)
  console.log(i); // 输出内部 i 的值,即 'abc'
} // 循环 3 次,每次输出 'abc'

效果

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

不存在变量提升

console.log(a); // var 声明提升,此时 a 已存在但未初始化,输出 undefined
var a = 1; // 执行赋值 a = 1(但本行之前输出已完成)

console.log(b); // let 存在暂时性死区(TDZ),声明前不可访问,抛出 ReferenceError
let b = 1; // 实际声明和初始化在本行,因上一行报错,本行不会执行

效果

PS C:\Users\Admin\Documents\node-learn> node var.js
undefined
C:\Users\Admin\Documents\node-learn\var.js:4
console.log(b);
            ^

ReferenceError: Cannot access 'b' before initialization
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\var.js:4:13)
    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

暂时性死区

var tmp = 123; // 外层作用域声明 tmp 并赋值为 123
if (true) {
  // 进入块级作用域,内部 let tmp 绑定该块
  tmp = "abc"; // 此 tmp 指向块内 let tmp(遮蔽外部同名变量)
  // ReferenceError           // let tmp 声明在前,赋值语句处于暂时性死区(TDZ),访问报错
  let tmp; // 实际声明位置,因上一行报错,本行不会执行
}

效果

S C:\Users\Admin\Documents\node-learn> node var1.js
C:\Users\Admin\Documents\node-learn\var1.js:4
  tmp = "abc"; // ReferenceError
      ^

ReferenceError: Cannot access 'tmp' before initialization
    at Object.<anonymous> (C:\Users\Admin\Documents\node-learn\var1.js:4: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

tips:代码旁的注释为 AIGC 负责生成



相关文章

社交的

bilibiliemailYouTube