Skip to content

描述下列代码的执行结果

js

foo(typeof a); function foo(p) { console.log(this); console.log(p); console.log(typeof b); let b = 0; }


## 参考答案:

最终答案:**输出全局对象、'undefined',然后抛出 ReferenceError 错误。**

这段代码涉及了几个关键点:**变量提升(Hoisting)**、**`typeof` 运算符的特性**、**函数作用域内的 `let` 声明的“暂时性死区”**,以及函数调用中的 **`this` 指向**。

### 一、代码分析

```js
foo(typeof a);

function foo(p) {
  console.log(this);
  console.log(p);
  console.log(typeof b);
  let b = 0;
}

二、运行步骤拆解

步骤 1:全局执行环境解析阶段

  • 函数 foo 被函数声明提升,因此在调用 foo(...) 时已可用;
  • a 并未声明;
  • 全局变量中没有 b,其声明在函数作用域内,且使用了 let,存在暂时性死区(TDZ)

步骤 2:执行 foo(typeof a)

  • typeof a:虽然变量 a 未定义,但 typeof 操作符在访问未声明变量时不会抛错,而是返回 'undefined'

    • 所以 typeof a 的值是 'undefined'
  • foo 被调用,参数 p 传入 'undefined'


步骤 3:函数 foo 开始执行

js
function foo(p) {
  console.log(this);    // (1)
  console.log(p);       // (2)
  console.log(typeof b);// (3)
  let b = 0;
}
  • (1) console.log(this); 在非严格模式下,this 指向 全局对象(浏览器中为 window,Node 中为 global; 若开启严格模式,则为 undefined;由于题目未开启严格模式,这里输出全局对象。

  • (2) console.log(p); 输出参数值,即 'undefined'

  • (3) console.log(typeof b); 关键点:变量 b 在此处已被创建,但尚未初始化(let 声明的特性),处于 TDZ(暂时性死区)。 访问它会触发 ReferenceError 异常。


三、执行结果(非严格模式下)

plaintext
<global object>  // console.log(this)
"undefined"      // console.log(p)
ReferenceError: Cannot access 'b' before initialization

题目要点:

  • typeof 未声明变量 不会抛错,会返回 'undefined'
  • let/const 声明的变量在所在作用域内存在暂时性死区(TDZ),在初始化之前访问会抛出 ReferenceError
  • 函数参数在执行前就已被初始化;
  • 非严格模式下函数中的 this 指向全局对象。