在定义之前使用javascript函数

时间:2013-12-13 01:09:14

标签: javascript function variables scope

在John Resig的“学习高级Javascript”幻灯片#6(http://ejohn.org/apps/learn/#6)中,您可以在定义之前使用某个功能。这是代码:

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; }; 

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

3 个答案:

答案 0 :(得分:3)

函数声明

function isNimble(){ return true; }

是在解析代码时(即在执行任何代码之前)定义的,其中函数表达式

var canFly = function(){ return true; };
代码运行时会计算

,因此在执行此行之前,该函数不可调用。这就是导致第二个例子失败的区别。

答案 1 :(得分:2)

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

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

以上链接的摘录可以很好地解释:

  

详细执行上下文

     

所以我们现在知道每次调用一个函数时,都会执行一个新的执行   上下文已创建。但是,在JavaScript解释器中,每一个   对执行上下文的调用有两个阶段:

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.

答案 2 :(得分:0)

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

当您处于代码中的某个点时,您应该知道调用函数时会发生什么。因此,该函数通常仅定义一次,或者已知优先顺序。功能实际上并不是为了改变而设计的,因此即使它们在代码的底部定义,也可以将它们提供给用户。

调用变量时,您希望在调用变量时获得该变量的值。如果在调用变量之前没有定义变量,它就不起作用。除此之外,这允许您在代码中的不同点为同一个变量分配不同的函数。


总而言之:不要将'after'与'below'混淆,只考虑在变量赋值之前进行简单的函数定义(即使你为该变量赋值函数)。