JavaScript 变量提升:变量和函数哪个会先被提升?

5

最近我对JavaScript的变量提升行为感到困惑,现在我被卡住了。

所以,有两个例子。

var alpha = 'alpha';

var beta = 'beta';

f(); //beta


var f = function f1() {
    console.log(beta);
};

function f() {
    console.log(alpha);
}

f(); // alpha

第一个函数按预期工作,因为当Javascript建立词法环境时,函数声明会覆盖变量f(值为“undefined”)。

但第二个函数让我有些困惑,我不理解其中的一些内容。

var alpha = 'alpha';

var beta = 'beta';

f();  // - alpha


function f() {
    console.log(alpha);
}

var f = function f1() {
    console.log(beta);
};


f(); // beta

为什么变量f没有被提升到代码顶部,而是在我们提升的函数之前被覆盖了呢?为什么在第一个f调用时我收到了"alpha"。我认为这必须是一个错误,比如:"f不是一个函数",因为在第一个f调用中,我期望f将是"undefined"。

1
从技术上讲,这两段代码片段是相同的。 - Jaromanda X
1
你可能会发现这个答案很有用。 - Mihailo
感谢所有的回答。 也许这个语句可以帮助一些像我一样不理解这个问题的人: 这就涵盖了变量提升,但函数提升呢?尽管两者都被称为“提升”,但行为实际上是非常不同的。与变量不同,函数声明不仅提升函数的名称,它还提升了实际的函数定义。 - Avernikoz
2个回答

2

给定 var foo = something,只有变量声明被提升。

这意味着 var foo 被提升,但是 foo = something 将按照读取顺序运行。

给定 function foo() {},变量声明和函数赋值都被提升。这将创建变量 foo 并将其赋值为该函数。

如果你两者都有,那么你就会重复声明变量(没有额外效果)并将其赋值为该函数(因为这是唯一的赋值)。

所以在你的第二个例子中...

函数声明被提升,所以 f(); // - first f 调用了它。

函数表达式的赋值没有被提升,但是 f(); // ** - second f 出现在它之后的正常读取顺序中,所以第二次调用 foo() 命中了它。


1

从技术上讲,这两个代码片段是相同的

类似于

function f() {
    console.log(alpha);
}
var alpha = 'alpha';
var beta = 'beta';
var f; // ignored because f is already defined
f();  // - first f
f = function f1() {
    console.log(beta);
};
f(); // ** - second f

也许 - 不过,我相当确定函数首先被"提升"

var alpha = 'alpha';
var beta = 'beta';
var f;
function f() {
    console.log(alpha);
}
f();  // - first f
f = function f1() {
    console.log(beta);
};
f(); // ** - second f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接