11

我是 Javascript 新手,对函数声明的工作方式感到困惑。我对此进行了一些测试并得到了一些有趣的结果:

say();

function say()
{
    alert("say");
}

前向声明有效并弹出“说”

在对面

say();

say = function()
{
    alert("say");
}

没用,虽然它也声明了一个函数对象

如果我们声明该函数并在之后重新声明它:

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

我得到的是“说”而不是“说”。那是惊喜!

好的。似乎只有最新的函数声明有效。然后让我们先声明函数对象,然后是“常规”函数:

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

另一个惊喜,是“speak”之后是“speak”。“常规”函数声明根本不起作用!

对所有这些都有解释吗?而且,如果“常规”函数声明真的那么“脆弱”并且可以很容易地被同名的函数对象覆盖,我应该远离它吗?

另一个问题是:只有函数对象格式,这种前向声明是不可能的吗?有没有办法在Javascript中“模拟”它?

4

4 回答 4

3

Javascript 的工作原理是这样的:

在执行实际语句之前,会解析文档,并function立即考虑所有声明。这解释了你的第一个例子。

如果将函数分配给局部变量,这是在执行期间完成的,因此您不能在第二个示例中使用该方法。

你的经验是,如果你两次声明一个函数,最后一个将被整个应用程序使用。这是你的第三个例子。

这些函数是window对象的成员,它们实际上是全局声明的。如果将局部变量分配给函数的值,则该局部变量优先于window对象中的成员。如果 javascript 找不到局部变量,它会在范围内向上搜索以找到它,该window对象是最后的手段。这就是您上一个示例中发生的情况,它有一个变量say,其范围比全局函数更具体say

如果您要say在运行时重新声明,即在上一个示例中交换声明的顺序,那么您会看到您期望的两个不同的警报:

say(); //speak, the global function

function say() {
  alert('speak');
}

var say = function() {
  alert('say');
}

say(); //say, the declared local variable
于 2010-01-15T15:38:24.873 回答
1
say();

function say()
{
    alert("say");
}

在这里,解释器获取say()它何时被调用的定义,并执行它。

say();

say = function()
{
    alert("say");
}

这里没有say()fetch 的定义 - 相反,您将匿名函数分配给变量。解释器无法“找到”它,就像它可以找到前向声明一样。

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

这里say被定义然后重新定义——最后一个定义胜出。

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

say是一个指向匿名函数的变量(在解释第一条语句之后)。这优先于任何函数定义,就像您将函数定义放在赋值之前一样。

但如果你有

say();

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

然后你会得到“说”,然后是“说”。

于 2010-01-15T15:39:01.980 回答
0

您可以期望按顺序应用您的函数定义。然后你所有的非方法代码行都会按顺序执行,包括函数对象的赋值。这解释了您的每个示例。不过,这是一个有趣的问题。在尝试调用函数对象,您真的无法分配函数对象,并期望它能够工作。但是,实际上将首先应用可执行代码之后的函数定义。

于 2010-01-15T15:38:02.013 回答
0

稍后调用该函数总是好主意,即使 javascript 就是这样工作的。

大多数语言不会那样工作,而是这样做。

function say(){
    alert("say");
}

say();

或者

say = function(){
    alert("say");
}

say();

或者

(function(){
    alert("say");
})();
于 2010-01-15T15:46:52.607 回答