为什么我可以在JavaScript中定义之前使用函数?

Edu*_*ipe 154 javascript function

即使在不同的浏览器中,此代码也始终有效:

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();
Run Code Online (Sandbox Code Playgroud)

但是,我无法找到它应该起作用的单一参考.我第一次在John Resig的演示文稿中看到过这个,但它只是提到了.那里或其他任何地方都没有解释.

有人可以赐教吗?

bob*_*nce 204

function声明是魔术并导致其标识符在其代码块*任何被执行前的约束.

这与带有function表达式的赋值不同,后者以正常的自上而下顺序进行计算.

如果你改变了例子说:

var internalFoo = function() { return true; };
Run Code Online (Sandbox Code Playgroud)

它会停止工作.

函数声明在语法上与函数表达式完全分离,即使它们看起来几乎相同并且在某些情况下可能不明确.

这在ECMAScript标准的10.1.3节中有记录.不幸的是ECMA-262即使按标准标准也不是一个非常易读的文档!

*:包含函数,块,模块或脚本.

  • @bobince好的,当我在此页面上找不到“提升”一词时,我开始怀疑自己。希望这些评论有足够的Google Juice™可以解决问题:) (2认同)
  • 这是一个流行的问题/答案组合.考虑使用ES5注释规范的链接/摘录进行更新.(哪个更容易获得.) (2认同)

Neg*_*gin 22

它被称为HOISTING - 在定义函数之前调用(调用)函数.

我想写的两种不同类型的函数是:

表达函数和减速函数

  1. 表达功能:

    函数表达式可以存储在变量中,因此它们不需要函数名.它们也将被命名为匿名函数(没有名称的函数).

    要调用(调用),他们总是需要使用变量名.如果在定义之前调用这意味着在此处不发生提升,则这些类型的功能将不起作用.我们必须首先定义表达式函数然后再调用它.

    let lastName = function (family) {
     console.log("My last name is " + family);
    };
    let x = lastName("Lopez");
    
    Run Code Online (Sandbox Code Playgroud)

    这是您在ECMAScript 6中编写的方法:

    lastName = (family) => console.log("My last name is " + family);
    
    x = lastName("Lopez");
    
    Run Code Online (Sandbox Code Playgroud)
  2. 减速功能:

    使用以下语法声明的函数不会立即执行.它们"保存供以后使用",并且在调用(调用)时将在稍后执行.如果您在定义它们之前或之后调用它们,这些类型的函数都有效.如果在定义之前调用减速功能 - 提升 - 正常工作.

    function Name(name) {
      console.log("My cat's name is " + name);
    }
    Name("Chloe");
    
    Run Code Online (Sandbox Code Playgroud)

    吊装示例:

    Name("Chloe");
    function Name(name) {
       console.log("My cat's name is " + name);
    }
    
    Run Code Online (Sandbox Code Playgroud)


dkr*_*etz 13

浏览器从头到尾读取您的HTML,并且可以在读取和解析为可执行的块(变量声明,函数定义等)时执行它.但是在任何时候都只能使用脚本之前定义的内容.

这与处理(编译)所有源代码的其他编程上下文不同,可能将它与您需要解析引用的任何库链接在一起,并构造可执行模块,此时执行开始.

您的代码可以引用已进一步定义的命名对象(变量,其他函数等),但在所有部分都可用之前,您无法执行引用代码.

随着您熟悉JavaScript,您将非常清楚地知道您需要以正确的顺序编写内容.

修订:要确认接受的答案(上面),请使用Firebug逐步浏览网页的脚本部分.在实际执行任何代码之前,您将看到它从功能跳到功能,仅访问第一行.

  • 答案结尾处的修订版+1,这是必不可少的部分. (6认同)

Too*_*the 5

某些语言要求标识符必须在使用前定义。其原因是编译器对源代码使用单遍。

但如果有多次通过(或某些检查被推迟),您可以在没有该要求的情况下完美地生活。在这种情况下,可能首先读取(并解释)代码,然后设置链接。