javascript 返回
变量声明是任何编程语言中最基本的方面之一。 但是,JavaScript有一个古怪的现象,称为hoisting ,它可以将无辜的声明变成一个细微的错误。 本文介绍什么是起重,以及如何避免被起重烧坏。
JavaScript是一种非常灵活的语言,很高兴可以让您在几乎任何地方声明变量。 例如,以下立即调用的函数表达式(IIFE)声明了三个变量,然后使用警告对话框显示它们。 附带说明一下,您永远不要使用警报框,但我们试图在此处证明这一点。
(function() {
var foo = 1;
var bar = 2;
var baz = 3;
alert(foo + " " + bar + " " + baz);
})();
这看起来像是理智JavaScript代码。 如预期的那样,它显示字符串"1 2 3"
。 现在,假设警报已移动,如下所示。
(function() {
var foo = 1;
alert(foo + " " + bar + " " + baz);
var bar = 2;
var baz = 3;
})();
如果有人真的写了这段代码,那可能是错误的。 显然,警报发生在声明bar
和baz
之前。 但是,这是完全有效JavaScript,不会生成异常。 而是,警报显示"1 undefined undefined"
。
根据我们之前的实验,您似乎可以引用尚不存在的变量。 现在,让我们使用相同的IIFE,但是完全删除baz
声明,如下所示。 突然,由于没有定义baz
,我们遇到了一个ReferenceError
。
(function() {
var foo = 1;
alert(foo + " " + bar + " " + baz);
var bar = 2;
})();
这是真正有趣的行为。 要了解这里发生的情况,您必须了解吊装。 提升是JavaScript解释器将所有变量和函数声明移至当前作用域顶部的动作。 但是,仅悬挂实际的声明。 任何作业都保留在原处。 因此,我们的第二个示例IIFE实际上转换为以下代码。
(function() {
var foo;
var bar;
var baz;
foo = 1;
alert(foo + " " + bar + " " + baz);
bar = 2;
baz = 3;
})();
现在很有意义,为什么第二个示例没有生成异常。 吊装后, bar
和baz
实际上是在alert语句之前声明的,尽管具有未定义的值。 在第三个示例中,完全删除了baz
。 因此,没有什么可提升的,并且警报语句导致异常。
功能吊装
如前所述,函数声明也被悬挂。 但是,不会提升分配给变量的功能。 例如,由于悬挂了函数声明,因此以下代码将按预期工作。
foo();
function foo() {
alert("Hello!");
}
但是,以下示例将严重失败。 foo
的变量声明在函数调用之前被吊起。 但是,由于未挂起对foo
的赋值,因此尝试调用非函数变量会引发异常。
foo();
var foo = function() {
alert("Hello!");
};
结论
吊装是一种易于理解的方法,但经常会忽略JavaScript语言的细微差别。 如果没有对提升的正确理解,您的程序很容易出现细微的错误。 为了避免这些错误,许多开发人员(和整理工具)在每个作用域的开始都主张使用单个变量声明语句。 由于这是JavaScript解释器从本质上看待您的代码的方式,因此该规则是有效的-即使我个人对此有罪。
翻译自: https://www.sitepoint.com/back-to-basics-javascript-hoisting/
javascript 返回