Variable hoisting
1 2 3 | alert(myVar1); return false; var myVar1; |
上面的代码在ie、ff和opera中抛出错误,说明函数中必须有返回语句。但它在Safari和Chrome中起作用(显示
以上代码是在全局范围内编写的。在所有功能之外。
有什么理由吗?
在javascript中,变量被移动到脚本顶部,然后运行。所以当你跑步的时候
1 2 3 | var myVar1; alert(myVar1); return false; |
这是因为JavaScript没有真正意义上的词汇范围。这就是为什么它被认为是最好的做法,把所有变量都声明在区域的顶部,它们将被用来防止提升引起问题。杰斯林特会为此抱怨的。
这篇文章很好地解释了这一点:http://www.adequatelygood.com/2010/2/javascript-scoping-and-lifting
返回无效。如果你想做一个真正的起重例子(取自上面的链接),做
1 2 3 4 5 6 7 8 | var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); |
这将警告10
评论后编辑
下面是我的理解,我已经在某个地方读过,但找不到我读到的所有资料来源,所以我愿意改正。
由于Javascript JIT的不同,这将发出警报。tracemonkey(http://ejohn.org/blog/tracemonkey/)我相信会使用javascript,快速进行静态分析,然后执行jit,然后尝试运行它。如果失败了,那么显然没有任何效果。
V8不进行静态分析,而是移动到JIT,然后运行这样的东西。它更像Python。如果在开发人员控制台(在Windows中为ctrl+shift+j)中运行chrome脚本,它将抛出一个错误,但也会运行以向您发出警报。
有时会用一种可能给人错误印象的方式解释提升,即变量和函数被javascript引擎提升,就好像它们被物理移动到了顶部,这实际上并不正确,如下面的代码所示:
1 2 | console.log(a); var a = 'Hello World!'; |
我们在控制台上看到的是
1 2 3 | var a; console.log(a); a = 'Hello World!'; |
不是的行为
1 2 | var a = 'Hello World!'; console.log(a); |
您可能会从变量和函数声明移到top语句中得到印象。
但JavaScript实际上并没有将代码移动到任何地方。您需要了解JavaScript中的执行上下文。它有两个阶段:创建阶段和执行阶段。在创建阶段,为这些变量和函数创建内存空间,人们似乎将这一步与提升混淆。实际上,javascript不会将代码移动到任何地方,发生的情况是,javascript已经为所有代码(即变量和函数)创建了内存空间,函数可以完全放在内存中,但在变量的情况下,分配是在执行上下文的执行阶段处理的。因此,当您执行var
ECMA-262第3版第12.9节(第75页)规定:
An ECMAScript program is considered syntactically incorrect if it contains a
return statement that is not within a FunctionBody.
也就是说,函数外部的
1 2 3 | alert(myVar1); return false; syntax error)))))))))))))))))); |
此外,第16节(第157页)规定:
An implementation may treat any instance of the following kinds of runtime errors as a syntax error and therefore
report it early:
- Improper uses of return, break, and continue.
火狐的引擎等。(即那些允许在全局范围内使用
An implementation shall report all errors as specified, except for the following:
- An implementation may provide additional types, values, objects, properties, and functions beyond those described in this specification. This may cause constructs (such as looking up a variable in the global scope) to have implementation-defined behaviour instead of throwing an error (such as ReferenceError).
此代码毫无意义:
var myVar1 将永远不会运行。return false; 不会返回任何东西,因为您不在函数中
opera、ie和ff抛出错误是正确的,因为此代码实际上是无效的,因为除非在函数中,否则无法返回。
如果它在Safari和Chrome中工作,那一定是因为他们使用的javascript引擎已经准备好处理错误代码了。我猜他们会看到"EDOCX1"(2),然后丢弃或替换为某种
有关函数的详细信息:http://www.w3schools.com/js/js_functions.asp
这是一个javascript提升的事情,简单地说,我们正在尝试打印变量的值,它不包含任何值。
javascript将上述代码呈现为:
1 2 3 | var myVar1 alert (myVar1) return false |
为了进一步说明,我参考了链接javascript提升:http://www.ufthelp.com/2014/11/javascript-lifting.html