可变吊装

alt*_*ter 33 javascript hoisting

alert(myVar1);
return false;
var myVar1;
Run Code Online (Sandbox Code Playgroud)

上面的代码在IE,FF和Opera中引发错误,说明return语句必须进入函数.但它undefined在Safari和Chrome中有效(显示).

上面的代码已经在全球范围内编写.在所有功能之外.

任何原因?

Aut*_*ter 35

在javaScript中,变量被移动到脚本的顶部然后运行.因此,当你运行它会做

var myVar1;
alert(myVar1);
return false;
Run Code Online (Sandbox Code Playgroud)

这是因为javascript确实没有真正意义上的词汇范围.这就是为什么它被认为是最好的做法,将所有变量声明在该区域的顶部,它们将用于防止吊装导致问题.JSLint会对此抱怨.

这是一篇很好的文章解释它 http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

退货无效.如果你想做一个真正的提升例子(取自上面的链接)呢

var foo = 1; 
function bar() { 
    if (!foo) { 
        var foo = 10; 
    } 
    alert(foo); 
} 
bar();
Run Code Online (Sandbox Code Playgroud)

这将提醒10

评论后编辑

以下是我的理解,我已经在某处读过它,但找不到我读过的所有资料,所以我愿意纠正.

此警报归功于JavaScript JIT的差异.TraceMonkey(http://ejohn.org/blog/tracemonkey/)我相信会接受JavaScript并进行快速静态分析,然后执行JIT然后尝试运行它.如果失败那么显然没有任何作用.

V8不进行静态分析,然后移动到JIT然后运行.它更类似于python.如果你在Chrome的开发者控制台中运行脚本(在Windows中按ctrl + shift + j),它会抛出一个错误,但也会运行以提醒你.

  • "在javaScript中,变量被移动到脚本的顶部,然后运行." 实际上,变量*名称*(而不是赋值/定义)被"提升"到包含范围的顶部(以最接近的为止;`if` et.al.do*not*在这种意义上创建"范围"). (4认同)

小智 17

有时提升会以一种可能给人错误印象的方式解释,即变量和函数被JavaScript引擎提升,好像它们被物理移动到顶部,这实际上并不正确,如下面的代码所示:

console.log(a);
var a = 'Hello World!';
Run Code Online (Sandbox Code Playgroud)

我们在控制台上看到的undefined不是'Hello World',所以我们得到了以下代码的行为

var a;
console.log(a);
a = 'Hello World!';
Run Code Online (Sandbox Code Playgroud)

不是的行为

var a = 'Hello World!';
console.log(a);
Run Code Online (Sandbox Code Playgroud)

您可以从变量和函数声明移到top语句中获得印象.

但JavaScript实际上并没有将代码移动到任何地方.您需要了解JavaScript中的执行上下文.它有两个阶段的创建阶段和执行阶段.在创建阶段,为这些变量和函数创建了内存空间,人们似乎将此步骤与提升相混淆.JavaScript实际上并没有将代码移动到任何地方,所发生的是JavaScript为所有代码创建了内存空间,即变量和函数,函数可以完全放在内存中,但是在变量的情况下,分配在执行上下文的执行阶段处理.所以当你做vara = 'Hello World!',JavaScript引擎知道它的值a当它在执行上下文的执行阶段开始执行它时,它会将一个占位符置为未定义,并且所有变量最初都在JavaScript中设置为undefined.所以依靠吊装并看到未定义是不好的.因此,在代码之上声明变量和函数总是好的.


str*_*ger 12

ECMA-262第3版第12.9节(第75页)指出:

如果ECMAScript程序包含return不在FunctionBody中的语句,则认为它在语法上是不正确的.

也就是说,return函数外部是语法错误.如果发生语法错误,则不运行任何代码.想想你的例子就像你写的那样:

alert(myVar1);
return false;
syntax error))))))))))))))))));
Run Code Online (Sandbox Code Playgroud)

此外,第16节(第157页)指出:

实现可能会将以下类型的运行时错误的任何实例视为语法错误,因此请尽早报告:

  • 返回,中断和继续使用不当.

Firefox的引擎等.人.(即,允许return在全局范围内的那些JavaScript实现)可能是符合的,假设以下子句(在同一部分中)允许return在全局范围内实现定义:

实施应报告指定的所有错误,但以下情况除外:

  • 实现可以提供除本说明书中描述的那些之外的其他类型,值,对象,属性和功能.这可能导致构造(例如在全局范围内查找变量)具有实现定义的行为而不是抛出错误(例如ReferenceError).