为什么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。 但是,他们仍然是对象。
另一方面,文字的true
, 0
, ""
和undefined
不是对象。 它们是JavaScript中的原始值。 然而,布尔值,数字和string也分别具有构造函数Boolean
, Number
和String
,它们分别包含它们各自的基元以提供附加的function:
console.log(typeof new Boolean(true)); // object console.log(typeof new Number(0)); // object console.log(typeof new String("")); // object
正如你所看到的,当原始值被包装在Boolean
, Number
和String
构造函数分别成为对象。 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
正如你所看到的typeof
和instanceof
不足以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;
你可以使用这个,它将适用于这两种情况
-
var text="foo";
/ / typeof将工作 -
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。