🍿 作用域变量代码输出题(1)

const n = 10

function print() {
 console.log(n)
}

function f1(fn) {
 const n = 20

 fn()
}

f1(print)

这段代码的输出结果是:10

详细解释:

代码执行流程:

  1. 声明全局变量 n = 10
  2. 定义函数 print()(打印 n 的值)
  3. 定义函数 f1(fn)
    • 声明局部变量 n = 20(仅在 f1 作用域内有效)
    • 调用传入的函数 fn()
  4. 执行 f1(print),将 print 函数作为参数传入

关键原理:

  1. 词法作用域(静态作用域)
    JavaScript 的作用域在函数定义时就已确定,而非运行时。print 函数在全局作用域中定义,因此它访问的 n 始终是全局变量 n
  2. 作用域链

    console.log(n)  // print 函数内部查找 n 的顺序:
    • 1️⃣ 当前函数作用域(print 内部)→ 未找到
    • 2️⃣ 外层作用域(全局作用域)→ 找到 n=10
  3. 局部变量不影响全局
    f1 内部的 const n = 20 是一个全新的局部变量,与全局 n 无关。

作用域图示:

全局作用域 (n=10)
│
├── print()  [访问全局 n]
│
└── f1()   
    │
    ├── 局部作用域 (n=20)  // 与全局 n 隔离
    │
    └── 调用 print()    // print 仍访问全局 n

对比实验:

如果 printf1 内部定义,结果会不同:

const n = 10;

function f1() {
  const n = 20;

  function print() {    // 在 f1 作用域内定义
    console.log(n);    // 访问局部 n
  }

  print(); // 输出 20
}

f1();

总结:

JavaScript 的函数作用域由定义位置决定(词法作用域)。
print 在全局定义,因此始终访问全局 n=10,不受 f1 内部局部变量的影响。