假设我有一些变量:
var s = 's', i = 0, o = {}, a = [], n = null, nan = NaN, u;
如何理解阅读x.p
何时会返回未定义的内容,何时会引发TypeError
?
s.p; // undefined
i.p; // undefined
o.p; // undefined
a.p; // undefined
n.p; // TypeError!
nan.p; // undefined
u.p; // TypeError!
P.S。 null
和undefined
是这种方式中唯一奇怪的值吗?还有其他人吗?
修改
我知道通过像我一样声明变量,我的几个值已被对象自动包装(例如Number
),尽管它们是基元。因此,我可以像对待他们一样对待他们。对象(例如{}
,[]
)并尝试读取其属性。但是,我无法找到解释这是什么和不包围的方式。
答案 0 :(得分:5)
是的,null
和undefined
是在属性访问中使用时抛出异常的唯一值。点和括号property accessors会调用内部CheckObjectCoercible function,其定义如下:
抽象操作
CheckObjectCoercible
如果出现错误则抛出错误 argument是一个无法转换为Object 的值ToObject
。它由表15定义:Table 15 — CheckObjectCoercible Results Argument Type | Result --------------+------------------ Undefined | Throw a TypeError exception. Null | Throw a TypeError exception. Boolean | Return Number | Return String | Return Object | Return
null
和undefined
是表示Nothing的值无法转换为对象("包裹"如您所说)。请注意,您当然可以拥有一个具有现有属性的对象,该对象会引发访问,例如
var o = {get p() { throw new TypeError("you may not access this"); }};
o.p // TypeError
答案 1 :(得分:1)
当你正在阅读那些未定义的东西时。你的基础是:
undefined未定义的是什么?或者在null的情况下什么是未定义的null? undefined和null都不是对象,因此您无法在它们之间设置或获取属性。考虑到这一点,将抛出错误。
答案 2 :(得分:1)
当对象为null / undefined时,它会抛出错误,因为它将尝试访问首先不存在的对象的属性。
在其他情况下,它将尝试访问现有对象的属性并返回undefined,因为找不到该属性。
请注意,js中的几乎所有内容都是对象,您可以看到here。
答案 3 :(得分:1)
让我们首先开始
为什么未定义:
var s='s';
您将s分配给基本类型的字符串。从某种意义上说,Javascript在这里很棘手。虽然是原始类型,但是当您尝试通过执行以下操作来访问该属性时:
s.p
首先在内部做到这一点:
String(s)
并创建对象,然后尝试查看它是否具有该属性,当然未定义,因此您未定义。数字赋值和NAN几乎相似。
n=null:
如果你这样做:
var n=null;
typeof n;//"object"
n.p// throws typeerror
实际上,null可以被认为是特殊类型的对象,没有任何属性或方法来表示缺少值,因此,当您尝试访问任何null属性时,会出现typeerror。
a.p
o.p
很容易,您可以看到您正在尝试访问对象的属性,而不是未定义或未内置,因此应该说,undefined。除了那个之外你应该感到惊讶:D。
答案 4 :(得分:0)
要在此处添加其他答案,可以轻松检查属性访问是否会引发异常。只需将您不确定的值与null
进行松散比较,就像这样:
if(x != null) { // note the LOOSE equality, rather than !==
// do something with x.prop
}
这样做的原因是只有null
和undefined
*在属性访问时抛出错误,并且它们只是松散地相互相等。请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_when_to_use_them。
*还有一些情况,某些JS对象显然可以“模拟”未定义,在这种情况下,它们也松散地等于null
和undefined
。