Why can I use a function before it's defined in JavaScript?
即使在不同的浏览器中,此代码也始终有效:
1 2 3 4 5 6 7 8 9 | function fooCheck() { alert(internalFoo()); // We are using internalFoo() here... return internalFoo(); // And here, even though it has not been defined... function internalFoo() { return true; } //...until here! } fooCheck(); |
但是,我无法找到它应该起作用的单一参考。
我第一次在John Resig的演示文稿中看到过这个,但它只是提到了。 那里或其他任何地方都没有解释。
有人可以赐教吗?
这与带有
如果你改变了例子说:
1 | var internalFoo = function() { return true; }; |
它会停止工作。
函数声明在语法上与函数表达式完全分离,即使它们看起来几乎相同并且在某些情况下可能不明确。
这在ECMAScript标准的第10.1.3节中有记录。不幸的是ECMA-262即使按标准标准也不是一个非常易读的文档!
*:包含函数,块,模块或脚本。
它被称为HOISTING - 在定义函数之前调用(调用)函数。
我想写的两种不同类型的函数是:
表达函数&减速功能
表达功能:
函数表达式可以存储在变量中,因此它们不需要函数名。它们也将被命名为匿名函数(没有名称的函数)。
要调用(调用),他们总是需要使用变量名。如果在定义之前调用这意味着在此处不发生提升,则这些类型的功能将不起作用。我们必须首先定义表达式函数然后再调用它。
1 2 3 4 | let lastName = function (family) { console.log("My last name is" + family); }; let x = lastName("Lopez"); |
这是您在ECMAScript中编写的方式  6:
1 2 3 | lastName = (family) => console.log("My last name is" + family); x = lastName("Lopez"); |
减速功能:
使用以下语法声明的函数不会立即执行。它们"保存供以后使用",并且在调用(调用)时将在稍后执行。如果您在定义它们之前或之后调用它们,这些类型的函数都有效。如果在定义之前调用减速功能 - 提升 - 正常工作。
1 2 3 4 | function Name(name) { console.log("My cat's name is" + name); } Name("Chloe"); |
吊装示例:
1 2 3 4 | Name("Chloe"); function Name(name) { console.log("My cat's name is" + name); } |
浏览器从头到尾读取您的HTML,并且可以在读取和解析为可执行的块(变量声明,函数定义等)时执行它。但是在任何时候都只能使用脚本之前定义的内容。
这与处理(编译)所有源代码的其他编程上下文不同,可能将它与您需要解析引用的任何库链接在一起,并构造可执行模块,此时执行开始。
您的代码可以引用已进一步定义的命名对象(变量,其他函数等),但在所有部分都可用之前,您无法执行引用代码。
随着您熟悉JavaScript,您将非常清楚地知道您需要以正确的顺序编写内容。
修订:要确认接受的答案(上面),请使用Firebug逐步浏览网页的脚本部分。在实际执行任何代码之前,您将看到它从功能跳到功能,仅访问第一行。
某些语言要求在使用前必须定义标识符。原因是编译器在源代码上使用单个传递。
但如果有多个通行证(或某些支票被推迟),你可以完全没有这个要求。
在这种情况下,可能首先读取(和解释)代码,然后设置链接。
我只使用了一点JavaScript。我不确定这是否会有所帮助,但它看起来与您所说的非常相似,可能会给出一些见解:
http://www.dustindiaz.com/javascript-function-declaration-ambiguity/
函数"internalFoo"的主体需要在解析时到达某处,因此当JS解释器读取代码(a.k.a解析)时,将创建函数的数据结构并分配名称。
只是在稍后,然后代码运行,JavaScript实际上试图找出"internalFoo"是否存在以及它是什么以及是否可以调用它等。
出于同样的原因,以下内容始终将
1 2 3 | if (test condition) { var foo; } |