为什么JavaScript中未声明变量会报not defined错误而非被提升?
问题解答
你混淆了两个完全不同的JavaScript机制:
- 变量提升:是编译阶段的行为,仅针对用
var/function等关键字声明的变量,会把声明提前到当前作用域的顶部 - 未声明变量赋值隐式创建全局变量:是运行时的行为,只有当赋值语句真正被执行的时候,才会触发这个逻辑
第一种代码报错的原因
你的第一段测试代码执行顺序如下:
console.log(x); function trial() { x = 5; console.log(x); } trial();
- 编译阶段扫描所有显式声明:整段代码没有任何地方显式声明
x,所以全局作用域、trial函数作用域都没有绑定x这个变量 - 开始执行代码,第一行就调用
console.log(x),此时trial函数还没有被调用,x = 5的赋值逻辑完全没有执行,自然不会触发「隐式创建全局变量」的逻辑,全局作用域里根本不存在x,所以直接抛出ReferenceError
如果把第一行的打印语句挪到trial()调用之后,就可以正常打印结果:
function trial() { x = 5; console.log(x); } trial(); console.log(x); // 输出5,此时x已经被trial函数隐式创建为全局变量
第二种代码输出undefined的原因
第二段代码你在顶部添加了var x的显式声明:
var x; console.log(x); function trial() { x = 5; console.log(x); } trial();
- 编译阶段识别到全局作用域的
var x声明,将这个声明提升到全局作用域顶部,此时x已经存在于全局作用域,默认赋值为undefined - 执行第一行
console.log(x)时,x已经被声明只是还没赋值,所以输出undefined,后续调用trial给x赋值为5,符合预期。
额外提示
这种未声明变量隐式创建全局变量的行为属于JavaScript的历史遗留缺陷,在严格模式(代码顶部添加'use strict')下会直接抛出错误,不会生成全局变量,日常开发中不建议使用这种写法,所有变量都应该先显式声明再使用。
内容的提问来源于stack exchange,提问作者abhishek vashistha
相关产品推荐
相关产品推荐

