谁能解释以下情况下的吊装行为?
alert(x);
var x = 10;
Result: alert-undefined
在下面的情况下,x 不是使用 'var' 关键字定义的 - 因此附加到全局范围。
alert(x);
x = 10; // not given a var
Result: error
如果我们用 window.x 替换 x,我们会得到未定义的警报!
alert(window.x); // calling the variable with window namespace
x = 10; // not given a var
Result: alert-undefined
你能解释一下为什么用变量名 (x( 和窗口命名空间 (window.x( 调用变量(附加到全局范围(是不同的吗?
术语"提升"经常被误解为意味着某些语句被移动到其执行上下文的顶部,这不是发生的事情,也是为什么应该避免使用这个词。
实际发生的情况是,首先处理所有声明,因此使用 var 声明的任何变量(以及由函数声明创建的任何函数(在执行任何代码之前都存在。然后开始执行代码。
因此,变量 x 是在执行任何代码之前创建并分配未定义的值(根据 ECMA-262(,然后,在执行期间,可能会为其分配一些值。
因此,在以下情况下:
alert(x);
var x = 10;
调用警报时 x 存在,但尚未分配未定义的值。
在:
alert(x);
x = 10;
x 未声明,因此在调用警报时它不存在,因此出现错误。警报发出后(如果代码继续运行(,对 x 的赋值将创建名为 x 的全局(浏览器中的窗口(对象的属性,并为其赋值 10。
在:
alert(window.x);
x = 10;
ECMAScript 的一个怪癖是全局变量也可以作为全局对象的属性使用。表达式window.x
尝试读取窗口对象的 x 属性。由于不存在此类属性,因此返回是未定义的。然后下一条语句将 x 创建为全局变量,因此 window.x 现在存在,其值为 10。
var x
将变量提升到它有效的整个作用域中,因此名称x
在作用域内的任何地方都可用且有效。它的初始值是 undefined
,它只在警报后收到它的值。
在普通x
的情况下,变量没有被吊起,因为没有var
,所以冒泡到window
和它的创建只发生在x = 10
行上,也就是在警报之后,这意味着变量在你尝试提醒它的时候是完全未定义的和无效的。
任何对象的任何不存在的属性都会返回undefined
,因此在未设置该属性时测试window.x
会按预期返回undefined
。这就是你在 Javascript 中进行成员资格测试的方式:检查特定属性是否等于 undefined
。
一种情况下,var x
被提升,所以当你调用它时x
确实存在(即使值未定义(
在第二种情况下,当你说y = 10
时,你实际上是在说window.y = 10
,所以根本没有提升,这就是为什么它根本找不到变量并给你一个错误。
alert(x);
var x = 10;
将被视为
var x;
alert(x);
x = 10;
所以在alert
x
的时候有default
undefined
的价值;
alert(x);
x = 10;
将被视为
alert(x);
x = 10; // If this line runs in use strict mode then this line will throw error otherwise in non strict mode x will be added to global object ie. window
throw error
也会因为x
在alert
时undefined
alert(window.x);
x = 10;
将被视为
alert(window.x);
x = 10;
警报将提醒undefined
,因为window
是一个object
,并且在alert
时它没有名为x
的属性,因此undefined
稍后,行x = 10;
会将x
添加到 global object
if in non strict mode
中,并将throw error
if 在 strict mode