[英]Defining functions after return
I'm currently reading John Papa's AngularJS style guide and saw the code : 我正在阅读John Papa的AngularJS风格指南,并看到了代码 :
function dataService() {
var someValue = '';
var service = {
save: save,
someValue: someValue,
validate: validate
};
return service;
////////////
function save() {
/* */
};
function validate() {
/* */
};
}
You can see that the functions save
and validate
are defined after the function returned a value. 您可以看到函数
save
和validate
是在函数返回值后定义的。 How does this work? 这是如何运作的? Is it standard-compliant and works in all browsers (say, from IE 6)?
它是否符合标准并适用于所有浏览器(例如,来自IE 6)?
You can see that the functions
save
andvalidate
are defined after the function returned a value.您可以看到函数
save
和validate
是在函数返回值后定义的。
That's what it looks like from where they're written, yes, but in fact they're defined before any step-by-step code in the function runs at all. 这就是从它们写入的地方看起来的样子,是的,但实际上它们是在函数中的任何分步代码运行之前定义的。 Sometimes this is called "hoisting" the declarations to the top of the function (something similar happens with
var
, too; more below). 有时这被称为“提升”声明到函数的顶部(类似的情况也发生在
var
;更多下面)。
When control enters an execution context (eg, when you enter a function, enter the global environment at the beginning of the program, or enter eval
code), one of the several things that happens before any step-by-step code is executed is that all of the function declarations in that context are processed and those functions are created. 当控件进入执行上下文时(例如,当您输入函数时,在程序开头输入全局环境,或输入
eval
代码), 在执行任何分步代码之前发生的几件事之一是处理该上下文中的所有函数声明并创建这些函数。 Since save
and validate
are defined by function declarations, they're created before the first step-by-step line of the code runs, and so it doesn't matter that they're after the return
. 由于
save
和validate
是由函数声明定义的,因此它们是在代码的第一个逐步行之前创建的,因此它们在return
之后并不重要。
Here's what the JavaScript engine does when you call a function (eg, when calling dataService
), with the function declarations step highlighted: 以下是JavaScript引擎在调用函数时所执行的操作(例如,在调用
dataService
),并突出显示了函数声明步骤:
this
this
env
) for the call env
) [[Scope]]
property on env
(this is part of how closures work) env
上设置对函数[[Scope]]
属性的引用(这是闭包工作方式的一部分) bindings
) for the environment to hold our the various names defined by the function (this is another part of how closures work, and also how variable references are resolved) bindings
)来保存我们由函数定义的各种名称(这是闭包如何工作的另一部分,以及如何解析变量引用) bindings
as a property referring to the function bindings
中 bindings
bindings
bindings
bindings
arguments
object, add it to bindings
arguments
对象,将其添加到bindings
var
to bindings
(if not already defined) with the value undefined
var
声明的每个变量添加到bindings
(如果尚未定义),并使用值undefined
This is laid out in excruciating detail in the spec in §10.4.1 and the sections it links to. 这在§10.4.1中的规范及其链接的部分中以极其详细的方式列出 。 (If you go to read that, brace yourself, the prose is...turgid...) That's a link to the current spec, but this was clearly laid out in §10 of the old third edition spec in 1999 as well, and I'm fairly sure it's been true right from the beginning.
(如果你去阅读那个,自我鼓励,散文就是......不稳定......)这是当前规范的一个链接,但这在1999年旧版第三版规范的§10中也有明确规定,而且我很确定从一开始就是如此。
Is it standard-compliant and works in all browsers (say, from IE 6)?
它是否符合标准并适用于所有浏览器(例如,来自IE 6)?
Yes. 是。 It used to make me nervous, so several years back (probably ~2005) I proved it to myself on all of the then-current and not-quite-dead browsers I could find (including IE6), and it was universally handled correctly.
它曾经让我感到紧张,所以几年前(可能〜2005年)我在我能找到的所有当时和非常死的浏览器(包括IE6)上证明了这一点,并且它得到了普遍正确的处理。 Which isn't actually surprising, because it's what makes this code work:
这实际上并不令人惊讶,因为它是使这段代码工作的原因:
doSomething();
function doSomething() {
// ....
}
...and people do that all the time . ......人们这样做, 所有的时间 。
This "hoisting" is one of the key differences between function declarations and function expressions . 这种“提升”是函数声明和函数表达式之间的关键差异之一。 If
save
and validate
were created by function expressions , then it would matter a great deal that they were written after the return
— they'd never get created at all: 如果
save
和validate
是由函数表达式创建的,那么return
后写入它们会很重要 - 它们永远不会被创建:
// It wouldn't work like this, for instance
function dataService() {
var someValue = '';
var service = {
save: save, // `save` has the value `undefined` at this point
someValue: someValue,
validate: validate // So does `validate`
};
return service;
////////////
var save = function() { // Now this is a function expression
/* */
};
var validate = function() { // This too
/* */
};
}
The save
and validate
variables would get created (thanks to Step 9 in the above), but as of where they're used, they'd have the value undefined
and so the returned object wouldn't be useful. 将创建
save
和validate
变量(由于上面的步骤9),但是在使用它们的地方,它们的值undefined
,因此返回的对象将没有用处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.