变量提升
alert(myVar1);
return false;
var myVar1;
上面的代码在IE,FF和Opera中抛出错误,说明返回语句必须进入函数。 但它在Safari和Chrome中起作用(显示undefined
)。
上面的代码已被写入全局范围。 除了所有的功能。
任何原因?
在javaScript中,变量被移动到脚本的顶部,然后运行。 所以当你运行它会做
var myVar1;
alert(myVar1);
return false;
这是因为javascript并没有真正的词汇范围界定。 这就是为什么它认为最好的做法是将所有变量声明在该区域的顶部,以防止吊装导致问题。 JSLint会对此抱怨。
这是一篇很好的文章,可以解释它http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Histing
退货是无效的。 如果你想做一个真正的提升的例子(取自上面的链接)做
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。 如果您在Chrome中的开发人员控制台中运行该脚本(在windows中按Ctrl + Shift + j),它将引发错误,但也会运行以提醒您。
有时,吊装的解释方式可能会给人以错误的印象,也就是说,JavaScript引擎会提升变量和功能,就好像它们实际上移动到顶端一样,但实际上并不正确,如下面的代码所示:
console.log(a);
var a = 'Hello World!';
我们在控制台上看到的是undefined
,而不是'Hello World'
,所以我们得到了以下代码的行为
var a;
console.log(a);
a = 'Hello World!';
不是行为
var a = 'Hello World!';
console.log(a);
您可能会从变量和函数声明被移至顶级语句中获得印象。
但是JavaScript实际上并不是在任何地方移动你的代码 您需要了解JavaScript中的执行上下文。 它有两个阶段创建阶段和执行阶段。 在创建阶段,为这些变量和函数创建内存空间,人们似乎将这一步与提升混为一谈。 JavaScript实际上并没有在任何地方移动代码,JavaScript会为所有代码创建内存空间,即变量和函数,函数可以完全放在内存中,但是在变量的情况下,分配会在执行上下文的执行阶段处理。 所以当你做var a = 'Hello World!'
,JavaScript引擎知道的值a
它开始在执行上下文的执行阶段执行它的时候,所以它把不确定的占位符,所有的变量都初始设置为undefined在JavaScript中。 所以依靠吊装和看不明确是不好的。 所以在代码之上声明变量和函数总是很好的。
ECMA-262第3版第12.9节(第75页)规定:
如果ECMAScript程序包含不在FunctionBody中的return
语句,则它被认为在语法上不正确。
也就是说,函数外的return
是语法错误。 如果发生语法错误,则不运行代码。 想想你的榜样,就好像你写过:
alert(myVar1);
return false;
syntax error))))))))))))))))));
另外,第16节(第157页)指出:
一个实现可能会将以下类型的运行时错误的任何实例视为语法错误,并因此提前报告:
Firefox的引擎等。 人。 (即那些允许在全局范围内return
JavaScript实现)可能是一致的,假设以下条款(在同一部分中)允许在全局范围内实现return
实现定义:
实施应按规定报告所有错误,但下列情况除外:
上一篇: Variable hoisting