为什么读取属性有时会在javascript中引发错误?

时间:2014-05-15 19:40:25

标签: javascript

假设我有一些变量:

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。 nullundefined是这种方式中唯一奇怪的值吗?还有其他人吗?

修改

我知道通过像我一样声明变量,我的几个值已被对象自动包装(例如Number),尽管它们是基元。因此,我可以像对待他们一样对待他们。对象(例如{}[])并尝试读取其属性。但是,我无法找到解释这是什么和不包围的方式。

5 个答案:

答案 0 :(得分:5)

是的,nullundefined是在属性访问中使用时抛出异常的唯一值。点和括号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

nullundefined是表示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
}

这样做的原因是只有nullundefined *在属性访问时抛出错误,并且它们只是松散地相互相等。请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_when_to_use_them

*还有一些情况,某些JS对象显然可以“模拟”未定义,在这种情况下,它们也松散地等于nullundefined