2013-12-13 63 views
2

在John Resig的“学习高级Javascript”幻灯片#6(http://ejohn.org/apps/learn/#6)中显示,您可以在定义函数之前使用它。这里是代码:在定义之前使用javascript函数

var canFly = function(){ return true; }; 
window.isDeadly = function(){ return true; }; 
assert(isNimble() && canFly() && isDeadly(), "Still works, even though isNimble is moved."); 
function isNimble(){ return true; } 

但是,我注意到下面的代码没有通过测试。

assert(canFly(), "Still works, even though isNimble is moved."); 
var canFly = function(){ return true; }; 

它看起来像一个匿名函数分配给一个变量不同于定义一个命名函数。这是为什么?这个概念的名称是什么,它描述了在语言定义之前使用函数的能力?

+0

[JavaScript'hoisting']的可能重复(http://stackoverflow.com/questions/15311158/javascript-hoisting) –

+0

搜索条件是“JavaScript hoisting” - 检查链接的副本(使用稍有不同的代码,但良好的链接) - 整个函数的变量是可见的(在'var'之前的方式),但只会在第一次赋值期间得到值。 –

+0

@AlexeiLevenkov对于范围而不是事物的顺序,最重要的不是答案吗? –

回答

3

函数声明:当代码被解析

function isNimble(){ return true; } 

被定义(即执行代码之前),wherease的函数表达式

var canFly = function(){ return true; }; 

进行评价时该代码正在运行,因此该函数在该行执行之后才能被调用。这是导致第二个示例失败的差异。

2

当Javascript创建执行上下文时,它首先创建所有变量,函数和参数。接下来它为它们赋值。由于isNimble是全局定义的函数,因此它在第一阶段与canFly一起创建,但是canFly在分配发生之后才会分配到第二阶段之后的功能。在执行assert语句之前,分配不会发生。

参见:http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/

下面是从上面的链接摘录解释得好:详情

执行上下文所以我们现在知道,每当一个函数被调用,创建新的执行 上下文。然而,JavaScript解释器内,每 调用执行上下文的有2个阶段:

Creation Stage [when the function is called, but before it executes any code inside]: 
    Create variables, functions and arguments. 
    Create the Scope Chain. 
    Determine the value of "this". 
Activation/Code Execution Stage: 
    Assign values, references to functions and interpret/execute code. 
+0

“既然'isNimble'是一个全局定义的函数,”应该是“因为'isNimble'是使用*函数声明*”定义的。 – RobG

+0

在引用的文本中,请注意[输入功能代码时](http://ecma-international.org/ecma-262/5.1/#sec-10.4.3)* ThisBinding *是第一个,而不是最后一个。 – RobG

0

这里的答案是为什么会发生(并有发生)。这不依赖于语言,我只是希望我没有使用javascript的奇怪术语。

当你在代码中的某个点时,你应该知道当你调用一个函数时会发生什么。因此该函数通常只定义一次,或者优先顺序已知。函数并不是真的被设计成可以改变的,所以即使它们在代码的底部被定义,它们也可以让用户使用。

当您调用变量时,您希望在调用变量时获得该变量的值。如果您在调用它之前没有定义变量,则该变量不起作用。除此之外,这允许您在代码的不同位置为同一变量分配不同的功能。


因此得出结论:与“自下而上”的“后”不要混淆,只是考虑变量赋值之前发生的简单函数的定义(即使你分配给该变量的函数)。

+0

它实际上取决于语言 - JavaScript将所有声明移至范围顶部(提升)。如果在声明前使用变量/函数,某些语言会出错... –

相关问题