是否有提升变量的目的?

Is there a purpose to hoisting variables?

我最近学习了很多 Javascript 并且我一直在尝试理解提升变量的值(如果有的话)。

我(现在)理解 JS 是一个两步系统,它编译然后执行。另外,我知道 var 关键字 'exists' 在它被声明的词法范围内,因此如果它在被引擎赋值之前被调用它是 'undefined' 的原因。

问题是,为什么这很重要?不提升就不行的变量提升有什么用呢?我觉得它只会创建可读性较差的代码而没有任何收获......

是否有提升变量有用的示例?

不是真的。我能想到的唯一有用的地方是,如果您匆忙编写代码并且碰巧稍后声明它。所以这并不重要,它是 JS 的一个奇怪的补充,很多人甚至都不知道,因为使用它感觉落后且效率低下。

"Hoisting" 对于相互递归函数(以及其他所有以循环方式使用变量引用的函数)是必需的:

function even(n) { return n == 0 || !odd(n-1); }
function odd(n) { return !even(n-1); }

如果没有 "hoisting",odd 函数将不在 even 函数的范围内。不支持它的语言需要 forward declarations,这不符合 JavaScript 的语言设计。

需要它们的情况可能比您想象的更频繁:

const a = {
    start(button) {
        …
        button.onclick = e => {
            …
            b.start(button);
        };
    }
};
const b = {
    start(button) {
        …
        button.onclick = e => {
            …
            a.start(button);
        };
    }
};

没有吊装这回事。提升只是发生的编译阶段的副作用以及 Javascript 是词法范围的事实。当编译器进入编译阶段时,它会在确定程序中存在的词法范围时将所有变量和函数声明放入内存中。但是没有 hoisting 函数或关键字或模块。事实上,在 es2015 发布之前,它甚至没有在 Ecmascript 规范中被引用。

归根结底,提升是我们都使用的百万美元词之一,通常是因为它更容易使用而不是解释和讨论 javascript 经历的编译过程。

我的建议是通读 Ecmascript 规范,研究 javascript 引擎源代码,如 v8,或者阅读 Kyle Simpson 的作品。他写了一个很棒的系列,叫做 You Don't Know JS。

希望对您有所帮助!

提升是一个在 ECMAScript® 2015 语言规范之前的任何规范规范散文中都找不到的术语。提升被认为是一种思考执行上下文(特别是创建和执行阶段)如何在 JavaScript 中工作的一般方法。但是,这个概念起初可能有点混乱。 例如,从概念上讲,提升的严格定义表明变量和函数声明在物理上移动到代码的顶部,但实际上并非如此。相反,变量和函数声明在编译阶段被放入内存,但准确地保留在您在代码中键入它们的位置。 <- 来自 Mozilla 文档

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting