JavaScript变量与函数提升场景下typeof(a)为number的原因咨询
问题代码
var a=2; function a(){}; console.log(typeof(a));
原因解释
核心原因是JavaScript的提升机制不是简单按代码书写顺序把声明挪到作用域顶部,不同类型声明的提升优先级、执行阶段的处理逻辑有明确规则:
- 同作用域下,函数声明的提升优先级高于
var变量声明:编译阶段会先处理所有函数声明,直接在作用域中创建对应变量并绑定函数体;之后再处理var声明,如果发现已经有同名变量,var的声明操作会直接被忽略,不会覆盖已有的值。 - 提升只处理「声明」部分,赋值操作永远是在代码执行阶段严格按书写顺序逐行运行的,函数声明在执行阶段碰到会直接跳过,不会重复执行赋值。
我们逐阶段拆解这段代码的运行过程:
- 编译(提升)阶段
- 先扫描所有函数声明,找到
function a(){},在全局作用域创建变量a,绑定为该函数,此时a的值就是函数a - 再扫描所有
var声明,找到var a,发现作用域内已经存在同名变量a,这条声明直接跳过,不做任何处理
- 先扫描所有函数声明,找到
- 执行阶段
- 运行第一行
var a=2:声明部分在提升阶段已经处理完毕,这行实际只执行赋值操作a = 2,原本绑定为函数的a被重新赋值为数字2 - 运行第二行
function a(){}:函数声明的全部逻辑在提升阶段已经处理完,执行阶段碰到直接跳过,不做任何操作 - 运行第三行
console.log(typeof(a)):此时a的值是数字2,所以输出number
- 运行第一行
可以对比下调换顺序的代码验证逻辑:
console.log(typeof(a)); // 输出function var a=2; function a(){};
这段代码打印时还没执行到a=2的赋值语句,所以拿到的是提升阶段绑定的函数值,类型才是function。
内容的提问来源于stack exchange,提问作者Alexzhang
相关产品推荐
相关产品推荐

