JavaScript中的函数顺序 [英] Order of functions in 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 ?
我认为,它:
- 扫描代码并简单地存储函数,而不是在全局环境中分配给任何var
- 以临时方式调用函数:当全局环境中没有这样的函数时,则抱怨。
推荐答案
在进入可执行上下文(例如,全局上下文)时处理函数声明或者函数调用),在正在处理的上下文中的任何分步代码之前。
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):
- 变量对象是为执行上下文创建的。
- 为每个
var
创建变量对象上的条目(实际上,字面上,属性)和上下文中的函数声明(加上一些其他的东西)。在你的情况下,那是f1
和f2
。最初属性的值为undefined
。 - 处理所有函数声明,因此:
-
f1
函数已定义并分配给变量对象的属性。 -
f2
函数已定义并分配给变量对象的属性。
-
- A "variable object" is created for the execution context.
- 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'sf1
andf2
. Initially the properties have the valueundefined
. - 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.
- The
更有趣的版本是:
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);
按此顺序发生:
-
foo
已创建(因为它是由声明定义的)。 -
警告
运行。 -
setTimeout
运行。 - (稍后)
foo
被调用。
foo
is created (since it's defined by a declaration).- The
alert
runs. - The
setTimeout
runs. - (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.
更多探索:
- 可怜的误解
var
- 关闭并不复杂(因为它讨论变量对象以及如何解析符号。
- Anonymousouses anonymous (详细说明命名函数表达式)
- 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屋!