Javascript Hoisting:调用x和window.x之间的区别



谁能解释以下情况下的吊装行为?

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也会因为xalertundefined

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

最新更新