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

2020/10/25 11:21 · javascript ·  · 0评论

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

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的演示文稿中看到了这一点,但仅被提及。那里或任何地方都没有解释。

有人可以启发我吗?

function声明是魔术,使它的标识符在代码块*中的任何内容执行之前就被绑定了。

这与带有function表达式的赋值不同,后者以正常的自上而下的顺序求值。

如果将示例更改为说:

var internalFoo = function() { return true; };

它将停止工作。

函数声明在语法上与函数表达式完全分开,即使它们看起来几乎相同并且在某些情况下可能是模棱两可的。

这在ECMAScript标准的10.1.3节中有说明不幸的是,即使按照标准标准,ECMA-262也不是一个易于阅读的文档!

*:包含的功能,块,模块或脚本。

这称为HOISTING-在定义函数之前调用(调用)函数。

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

表达式函数和声明函数

  1. 表达式功能:

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

    要调用(调用)这些函数,它们始终需要一个变量名如果在定义之前调用该函数,则该函数将不起作用,这意味着此处未发生吊装。我们必须始终先定义表达式函数,然后再调用它。

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

    这是您如何在ECMAScript 6中编写它:

    lastName = (family) => console.log("My last name is " + family);
    
    x = lastName("Lopez");
    
  2. 声明功能:

    用以下语法声明的函数不会立即执行。它们被“保存以备后用”,并且将在它们被调用时被执行。如果在定义位置之前或之后调用此功能,则此类型的功能有效。如果在定义之前调用声明函数,则吊装工作正常。

    function Name(name) {
      console.log("My cat's name is " + name);
    }
    Name("Chloe");
    

    吊装示例:

    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解释器读取(也称为解析)代码时,将创建该函数的数据结构并分配名称。

直到稍后,然后运行代码,JavaScript实际上试图找出“ internalFoo”是否存在,它是什么以及是否可以调用等。

出于相同的原因,以下内容将始终放在foo全局名称空间中:

if (test condition) {
    var foo;
}
本文地址:http://javascript.askforanswer.com/weishenmezaijavascriptzhongdingyihanshuzhiqianjiukeyishiyongta.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!