不一致的实例

时间:2011-12-20 00:22:39

标签: javascript

有人可以解释一下吗?

[] instanceof Array; // true
'' instanceof String; // false

4 个答案:

答案 0 :(得分:14)

请注意以下事项:

"" instanceof String;             // => false
new String("") instanceof String; // => true

instanceof需要一个对象,但""是字符串文字,而不是String对象。使用typeof函数注意以下类型:

typeof ""             // => "string"
typeof new String("") // => "object"
typeof []             // => "object"
typeof new Array()    // => "object"

答案 1 :(得分:11)

这是因为''是原始的,而不是对象。

JavaScript中的一些原语可以有一个对象包装器。当您使用带有new的内置构造函数创建包装器的实例时,会创建这些。

new通常是必需的,因为如果排除new,函数通常会强制转换为基元。

typeof new String('');  // "object"
typeof String('');      // "string"
typeof '';              // "string"

具有Object包装器的原语是stringnumberboolean

不是nullundefined的基元。

答案 2 :(得分:3)

''不是任何事情的实例;它是一种原始类型,它的工作方式与5.5true大致相同。字符串基元和String对象之间存在差异。参见:

new String('') instanceof String; // true

使用new String()new Number()new Boolean()创建的任何内容都是基本类型的对象包装器,它们并不相同。

要检查字符串等,请改为使用typeof

typeof '' === 'string'; // true

要检查两者,请使用:

Object.prototype.toString.call('') === '[object String]'; // true
Object.prototype.toString.call(new String('')) === '[object String]'; // true

Object.prototype.toString.call用于通用代码,数组,字符串,数字布尔值有几个原因。他们是:

  1. 对于字符串,数字和布尔值,人们可以传递包装器对象的实例而不是基元类型。它们通常以相同的方式运行(使用隐式valueOf()),因此在编写库代码时应该接受它们。
  2. 对于数组,如果您从另一个窗口(例如来自<iframe>)收到数组,则使用instanceof Array将返回falseObject.prototype.toString.call方法适用于所有目的。
  3. 这是jQuery和其他大型流行的库所做的。

答案 3 :(得分:1)

我已经做了一些挖掘,我想它与string interning有关,这是一个编译器优化。

好的,准备好了一些陷阱? :d

"abc" == "abc"; // true
"abc" === "abc"; // true

我认为这是正确的,因为“字符串实习”在概念上也恰好也很有意义(对于'正确的'字符串'而言)。

new String("abc") == new String("abc"); // false
new String("abc") === new String("abc");    // false

如果假设String是一个对象并且一个对象仅等于它自己并且不等于具有相似内部状态的对象,则这是有意义的。就像在Java中一样(或者以前的方式)。

现在为了踢球者:

(new String("abc")).substr(0,3) === (new String("abc")).substr(0,3); // true!

显然,JavaScript解释器总是更喜欢使用String对象进行字符串实习。

然后我必须问一下,String对象的用途是什么?显然它与朋友的关系并不好。