为什么instanceof返回false为一些文字?

"foo" instanceof String //=> false "foo" instanceof Object //=> false true instanceof Boolean //=> false true instanceof Object //=> false false instanceof Boolean //=> false false instanceof Object //=> false // the tests against Object really don't make sense 

数组文字和对象文字匹配…

 [0,1] instanceof Array //=> true {0:1} instanceof Object //=> true 

为什么不全部? 或者,他们为什么不全都不
那么,它们是什么呢?

在FF3,IE7,Opera和Chrome中都是一样的。 所以,至less是一致的。


错过了几个。

 12.21 instanceof Number //=> false /foo/ instanceof RegExp //=> true 

基元是与在Javascript中创build的对象不同的types。 从Mozilla API文档 :

 var color1 = new String("green"); color1 instanceof String; // returns true var color2 = "coral"; color2 instanceof String; // returns false (color2 is not a String object) 

我找不到用代码构build原始types的方法,也许这是不可能的。 这可能是为什么人们使用typeof "foo" === "string"而不是instanceof

一个简单的方法来记住这样的事情是问自己:“我想知道什么是理智和容易学习”? 不pipe答案是什么,Javascript都会做另一件事情。

我用:

 function isString(s) { return typeof(s) === 'string' || s instanceof String; } 

因为在JavaScript中string可以是文字或对象。

在JavaScript中,除了基本types (布尔值,空值,数字,string和undefined的值(以及ES6中的符号)),一切都是一个对象(或者可能至less被视为一个对象):

 console.log(typeof true); // boolean console.log(typeof 0); // number console.log(typeof ""); // string console.log(typeof undefined); // undefined console.log(typeof null); // object console.log(typeof []); // object console.log(typeof {}); // object console.log(typeof function () {}); // function 

正如你所看到的对象,数组和null都被认为是对象( null是对不存在的对象的引用)。 函数是有区别的,因为它们是可调用对象的一种特殊types。 但是,他们仍然是对象。

另一方面,文字的true0""undefined不是对象。 它们是JavaScript中的原始值。 然而,布尔值,数字和string也分别具有构造函数BooleanNumberString ,它们分别包含它们各自的基元以提供附加的function:

 console.log(typeof new Boolean(true)); // object console.log(typeof new Number(0)); // object console.log(typeof new String("")); // object 

正如你所看到的,当原始值被包装在BooleanNumberString构造函数分别成为对象。 instanceof运算符只能用于对象(这就是为什么对于原始值返回false ):

 console.log(true instanceof Boolean); // false console.log(0 instanceof Number); // false console.log("" instanceof String); // false console.log(new Boolean(true) instanceof Boolean); // true console.log(new Number(0) instanceof Number); // true console.log(new String("") instanceof String); // true 

正如你所看到的typeofinstanceof不足以testing一个值是一个布尔值,一个数字还是一个string – typeof只适用于原始的布尔值,数字和string; 而instanceof不适用于原始的布尔值,数字和string。

幸运的是,这个问题有一个简单的解决scheme。 toString的默认实现(也就是它本身在Object.prototype.toString定义)返回原始值和对象的内部[[Class]]属性:

 function classOf(value) { return Object.prototype.toString.call(value); } console.log(classOf(true)); // [object Boolean] console.log(classOf(0)); // [object Number] console.log(classOf("")); // [object String] console.log(classOf(new Boolean(true))); // [object Boolean] console.log(classOf(new Number(0))); // [object Number] console.log(classOf(new String(""))); // [object String] 

值的内部[[Class]]属性比值的types更有用。 我们可以使用Object.prototype.toString来创build我们自己的(更有用的) typeof运算符的版本,如下所示:

 function typeOf(value) { return Object.prototype.toString.call(value).slice(8, -1); } console.log(typeOf(true)); // Boolean console.log(typeOf(0)); // Number console.log(typeOf("")); // String console.log(typeOf(new Boolean(true))); // Boolean console.log(typeOf(new Number(0))); // Number console.log(typeOf(new String(""))); // String 

希望这篇文章有帮助。 要了解基元和包装对象之间的差异,请阅读以下博文: JavaScript Primitives的秘密生活

你可以使用构造函数属性:

 'foo'.constructor == String // returns true true.constructor == Boolean // returns true 
  typeof(text) === 'string' || text instanceof String; 

你可以使用这个,它将适用于这两种情况

  1. var text="foo"; / / typeof将工作

  2. String text= new String("foo"); // instanceof将工作

我相信我已经想出了一个可行的解决scheme:

 Object.getPrototypeOf('test') === String.prototype //true Object.getPrototypeOf(1) === String.prototype //false 

对我造成的困惑

 "str".__proto__ // #1 => String 

所以"str" istanceof String应该返回true因为如何工作如下:

 "str".__proto__ == String.prototype // #2 => true 

expression#1#2的结果相互冲突,所以应该有其中一个错误。

#1是错误的

我发现它由__proto__引起的是非标准的属性,所以使用标准的属性: Object.getPrototypeOf

 Object.getPrototypeOf("str") // #3 => TypeError: Object.getPrototypeOf called on non-object 

expression式#2#3之间没有混淆

我用这个来解决:

 function typeOf(value) { var ret = typeof value; // adjusting type based on object instanceof if (ret === 'object') { if (value instanceof Date) { ret = 'date'; } else if (value instanceof Number) { ret = 'number'; } else if (value instanceof String) { ret = 'string'; } else if (value instanceof Boolean) { ret = 'boolean'; } } return ret; } 

或者你可以像这样做自己的function:

 function isInstanceOf(obj, clazz){ return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase()); }; 

用法:

 isInstanceOf('','String'); isInstanceOf(new String(), 'String'); 

这些都应该返回true。

那是因为这些东西是原始的 ,除非它们需要被用作对象(例如当你调用方法时),它们仍然是如此。 他们“成为”对象唯一的时候是他们需要被包装的时候。 如果你熟悉.NET中“装箱”的概念,那么就这样想。

这里是一个例子 – 看看这个代码:

 Number.prototype.times = function(func) { for(var index = 1; index <= this; index++) { func(index); } }; 

所以,下面的代码将失败:

 3.times(print); // assume 'print' writes to standard out 

3,本身就是一个原始的。 这就是说,以下将起作用:

 (3).times(print); // assume 'print' writes to standard out 

这将显示数字1,2和3.由于括号的原因,JavaScript解释器将暂时将原语3包装在一个Number对象中,调用该方法,然后垃圾收集该对象,因为它不再需要。

无论如何,这个完整的讨论可以在“JavaScript:权威指南”中find