以下两个语句(在全局窗口的上下文中)有什么区别?
(function() { return a; } )(); // ReferenceError: a is not defined
(function(a) { return a; } )(); // returns undefined
我认为它与以下内容有关:
a; // ReferenceError: a is not defined
window.a; // undefined
似乎第二个函数沿着作用域链上升并结束于全局窗口作用域,其中 a
不是窗口的属性,因此返回 undefined
。但是第一个函数不应该也做同样的事情并返回 undefined
吗?
我找到了这个 SO question关于未定义与未定义,但它似乎更适用于与变量相关的内容,而不是与窗口范围内的属性相关的内容。
最佳答案
我认为这是一个常见的陷阱和一个重要的问题,如果您正在阅读本文并且有什么不清楚,请在评论中告诉我。
简而言之
a;
- 将抛出一个引用错误,因为它试图访问一个 undefined variablefunction() { 返回一个; } )();
- 这与上面的情况完全一样,它是对 undefined variable 的访问object.a
- 将返回 undefined,我们在这里不是要访问 undefined variable ,而是要访问已知对象的属性,这是不同的(function(a) { return a; } )();
- 将返回 undefined,a
是这里的参数而不是 undefined variable ,它将被分配实际的语言原始值类型undefined
。
让我们再深入一点好吗?
规范
让我们看看语言规范对所有这些情况是怎么说的:
未声明的变量引用
规范说明 here:
If IsUnresolvableReference(V), throw a ReferenceError exception.
规范指出:
IsUnresolvableReference(V). Returns true if the base value is undefined and false otherwise.
这就是为什么会发生以下情况:
a; // ReferenceError: a is not defined
由于未定义基值,因此它会按照规范指定的方式抛出引用错误。
未声明的对象属性
在一个对象中,base 不是未定义的(它是对象)所以一切都很好并且不会抛出任何错误。它是这样解决的:
The following [[Get]] internal method is used by GetValue when V is a property reference with a primitive base value. It is called using base as its this value and with property P as its argument. The following steps are taken:
Let O be ToObject(base).
Let desc be the result of calling the [[GetProperty]] internal method of O with property name P.
If desc is undefined, return undefined.
这就是为什么你会看到:
window.a; // undefined
函数参数
另一种情况——参数完全不同,参数存在,但它的值被设置为未定义的原始值类型。 existing 和 being undefined 和 not existing 是有区别的:)
这是 specified here :
If n is greater than argCount, let v be undefined otherwise let v be the value of the n’th element of args.
这是为什么:
(function(a) { return a; } )(); // returns undefined
关于javascript - JavaScript 中未定义与已定义的窗口属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17288317/