惊讶的是全局variables在JavaScript中有未定义的值
今天,当我看到一个全局variables在某些情况下具有undefined
值时,我完全感到惊讶。
例:
var value = 10; function test() { //A console.log(value); var value = 20; //B console.log(value); } test();
给出输出
undefined 20
这里,为什么JavaScript引擎将全局值视为undefined
。 我知道JavaScript是一种解释型语言。 它如何能够考虑函数中的variables?
这是JavaScript引擎的陷阱吗?
这种现象被称为: JavaScriptvariables提升 。
你在任何时候都不能访问你的函数中的全局variables。 你只能访问本地value
variables。
您的代码等同于以下内容:
var value = 10; function test() { var value; console.log(value); value = 20; console.log(value); } test();
仍然感到惊讶,你undefined
?
说明:
这是每个JavaScript程序员迟早会遇到的事情。 简而言之,无论您声明的variables总是被提升到本地closures的顶部。 所以,即使你在第一个console.log
调用之后声明了你的variables,它仍然被认为是在你之前声明的。
但是,只有宣布部分正在悬挂; 另一方面,这项任务并不是。
所以,当你第一次调用console.log(value)
,你正在引用你的本地声明的variables,它还没有分配给它。 因此undefined
。
这是另一个例子 :
var test = 'start'; function end() { test = 'end'; var test = 'local'; } end(); alert(test);
你认为这会提醒什么? 不,不要只读,想想。 test
的价值是什么?
如果你说的不是start
,你错了。 上面的代码等同于:
var test = 'start'; function end() { var test; test = 'end'; test = 'local'; } end(); alert(test);
这样全局variables就不会受到影响。
正如你所看到的,不pipe你把你的variables声明放在哪里,它总是被挂到你的本地闭包的顶部。
边注:
这也适用于function。
考虑这段代码 :
test("Won't work!"); test = function(text) { alert(text); }
这会给你一个参考错误:
Uncaught ReferenceError:testing未定义
这引发了很多开发人员,因为这段代码工作正常:
test("Works!"); function test(text) { alert(text); }
如上所述,这是因为分配部分没有被吊起来。 所以在第一个例子中,当test("Won't work!")
被运行时, test
variables已经被声明,但是还没有赋予它的function。
在第二个例子中,我们没有使用variables赋值。 相反,我们正在使用正确的函数声明语法,它完全提升了函数。
Ben Cherry已经写了一篇很好的文章,标题为JavaScript范围和提升 。
阅读。 它会给你全面的细节。
我对这个问题的解释有些失望,但没有人提出解决scheme。 如果要访问函数范围中的全局variables,而无需首先创build未定义的局部variables函数,请将var引用为window.varName
JavaScript中的variables总是具有函数范围。 即使它们在函数的中间被定义,它们之前也是可见的。 function提升可能会出现类似现象。
这就是说,第一个console.log(value)
看到value
variables(内部的阴影外部value
),但尚未初始化。 你可以把它看作好像所有的variables声明都被隐式地移到了函数的开头( 而不是最内部的代码块),而定义被放在同一个地方。
也可以看看
- Javascriptfunction范围和提升
- 在函数头部的Javascriptvariables声明
有一个全局variablesvalue
,但是当控制进入test
函数时,声明了另一个value
variables,这个variables会影响全局值。 由于JavaScript中的variables声明( 但不是分配 )被提升到声明范围的顶部:
//value == undefined (global) var value = 10; //value == 10 (global) function test() { //value == undefined (local) var value = 20; //value == 20 (local) } //value == 10 (global)
请注意,函数声明也是如此,这意味着您可以在代码中定义之前调用函数:
test(); //Call the function before it appears in the source function test() { //Do stuff }
还值得注意的是,当你将两者结合成一个函数expression式时,这个variables将是undefined
直到分配发生,所以你不能调用该函数,直到发生这种情况:
var test = function() { //Do stuff }; test(); //Have to call the function after the assignment