JavaScript中的函数顺序 [英] Order of functions in JavaScript

查看:78
本文介绍了JavaScript中的函数顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是基于这本书的例子。面向对象的JavaScript (第81页 - 词汇范围)

My question is based on the example from a book "Object Oriented JavaScript" (page 81 - Lexical Scope)

所以,我从这个例子中理解......

So, i understand from this example ...

function f1(){var a = 1; f2();}
function f2(){return a;}
f1();

......那:


a未定义

但是,f1如何了解f2,这是在f1之后定义的吗?

But, how f1 get's to know about f2, which is defined after f1 ?

这种行为引发了一个问题:

This behavior raises a question:

JavaScript解释器的工作原理是什么?

How JavaScript interpreter works ?

我认为,它:


  1. 扫描代码并简单地存储函数,而不是在全局环境中分配给任何var

  2. 以临时方式调用函数:当全局环境中没有这样的函数时,则抱怨。


推荐答案

在进入可执行上下文(例如,全局上下文)时处理函数声明或者函数调用),在正在处理的上下文中的任何分步代码之前。

Function declarations are processed upon entry into an executable context (e.g., the global context, or a function call), prior to any of the step-by-step code in the context being processed.

所以在你的代码中,这些事情发生了(在这里订单):

So in your code, these things happen (in this order):


  1. 变量对象是为执行上下文创建的。

  2. 为每个 var 创建变量对象上的条目(实际上,字面上,属性)和上下文中的函数声明(加上一些其他的东西)。在你的情况下,那是 f1 f2 。最初属性的值为 undefined

  3. 处理所有函数声明,因此:


    • f1 函数已定义并分配给变量对象的属性。

    • f2 函数已定义并分配给变量对象的属性。

  1. A "variable object" is created for the execution context.
  2. Entries (actually, literally, properties) on the "variable object" are created for every var and function declaration in the context (plus a few other things). In your case, that's f1 and f2. Initially the properties have the value undefined.
  3. All function declarations are processed, and so:
    • The f1 function is defined and assigned to its property on the variable object.
    • The f2 function is defined and assigned to its property on the variable object.

更有趣的版本是:

f1();
function f1(){var a = 1; f2();}
function f2(){return a;}

...它发生在上面列出的完全相同的订单中,因为两个声明都是在第一行逐步代码之前处理的。

...which happens in exactly the same order listed above, because both of the declarations are handled before the first line of step-by-step code.

函数声明与函数表达式不同,它们就像在逐步执行代码时到达任何其他表达式一样进行评估。函数表达式是指您创建函数并将其用作右侧值时,例如,将结果赋值给变量或将其传递给另一个函数。像这样:

Function declarations are different from function expressions, which just like any other expression are evaluated when they're reached in the step-by-step execution of the code. A function expression is any time you create a function and use it as a right-hand value, e.g., assign the result to a variable or pass it into another function. Like this:

var f2 = function() {
};

或者

setTimeout(function() {
    alert("Hi there");
}, 1000);

请注意,我们正在使用函数的结果语句作为右侧值(在赋值中,或通过将其传递给函数)。那些在进入执行上下文时(例如,不在上面的步骤3中)进行预处理,它们在代码流到达它们时被处理。这导致:

Note that we're using the result of the function statement as the right-hand value (in an assignment, or by passing it into a function). Those are not pre-processed upon entry into an execution context (e.g., not at Step 3 above), they're handled when the flow of code reaches them. Which leads to:

f1();
function f1(){var a = 1; f2();}
var f2 = function(){return a;};

...失败,因为 f2 在被调用时是未定义的。

...which fails, because f2 is undefined as of when it's called.

您可以将声明函数的值用作右手值而不将其转换为函数表达式(我们一直这样做) ),只要你在两个单独的陈述中这样做。所以:

You can use a declared function's value as a right-hand value without turning it into a function expression (we do that all the time), so long as you do it in two separate statements. So:

alert("Beginning");
function foo() { ... }
setTimeout(foo, 100);

按此顺序发生:


  1. foo 已创建(因为它是由声明定义的)。

  2. 警告运行。

  3. setTimeout 运行。

  4. (稍后) foo 被调用。

  1. foo is created (since it's defined by a declaration).
  2. The alert runs.
  3. The setTimeout runs.
  4. (Later) foo is called.

最后一点:虽然他们是 工作,包含函数 name 的函数表达式在所有实现上都不能可靠地运行,并且现在必须避免:

One last point: Although they should work, a function expression that includes a function name does not work reliably on all implementations and must, for now, be avoided:

var f = function foo() { ... }; // <== DON'T DO THIS

setTimeout(function foo() {     // <== DON'T DO THIS
}, 1000);

特别是Internet Explorer存在问题,其他实现也有不同的时间。

Internet Explorer, in particular, has issues with those, and other implementations have at various times as well.

更多探索:

  • Poor misunderstood var
  • Closures are not complicated (because it talks about variable objects and how symbols are resolved)
  • Anonymouses anonymous (talks more about named function expressions)

这篇关于JavaScript中的函数顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆