惊讶的是全局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。 你只能访问本地valuevariables。

您的代码等同于以下内容:

 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!")被运行时, testvariables已经被声明,但是还没有赋予它的function。

在第二个例子中,我们没有使用variables赋值。 相反,我们正在使用正确的函数声明语法,它完全提升了函数。


Ben Cherry已经写了一篇很好的文章,标题为JavaScript范围和提升 。
阅读。 它会给你全面的细节。

我对这个问题的解释有些失望,但没有人提出解决scheme。 如果要访问函数范围中的全局variables,而无需首先创build未定义的局部variables函数,请将var引用为window.varName

JavaScript中的variables总是具有函数范围。 即使它们在函数的中间被定义,它们之前也是可见的。 function提升可能会出现类似现象。

这就是说,第一个console.log(value)看到valuevariables(内部的阴影外部value ),但尚未初始化。 你可以把它看作好像所有的variables声明都被隐式地移到了函数的开头( 而不是最内部的代码块),而定义被放在同一个地方。

也可以看看

  • Javascriptfunction范围和提升
  • 在函数头部的Javascriptvariables声明

有一个全局variablesvalue ,但是当控制进入test函数时,声明了另一个valuevariables,这个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