Javascript 为什么instanceof对于某些文本返回false?
数组文字和对象文字匹配Javascript 为什么instanceof对于某些文本返回false?,javascript,literals,instanceof,Javascript,Literals,Instanceof,数组文字和对象文字匹配 "foo" instanceof String //=> false "foo" instanceof Object //=> false true instanceof Boolean //=> false true instanceof Object //=> false false instanceof Boolean //=> false false instanceof Object //=
"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
为什么不是所有人?或者,为什么他们都不呢?那么,它们是什么样的例子呢
在FF3、IE7、Opera和Chrome中也是如此。所以,至少它是一致的。原语是一种不同于Javascript中创建的对象的类型。从: 我找不到用代码构造基元类型的任何方法,也许这是不可能的。这可能就是为什么人们使用
类型的“foo”==“string”
而不是实例的原因
记住这类事情的一个简单方法是问自己“我想知道什么是理智的、容易学的”?不管答案是什么,Javascript做的是另一件事。您可以使用构造函数属性:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
或者,您可以像这样创建自己的函数:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
用法:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
这两者都应返回true。我使用:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
因为在JavaScript中,字符串可以是文本或对象。在JavaScript中,所有内容都是对象(或者至少可以被视为对象),除了(布尔值、null、数字、字符串和未定义的值(以及ES6中的符号)):
如您所见,对象、数组和值null
都被视为对象(null
是对不存在的对象的引用)。函数之所以与众不同,是因为它们是一种特殊类型的可调用对象。然而,它们仍然是对象
另一方面,文本true
、0
、“
和未定义的
不是对象。它们是JavaScript中的基本值。但是布尔、数字和字符串也分别具有构造函数Boolean
、Number
和String
,它们包装各自的原语以提供附加功能:
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
正如您所看到的,当基本值分别包装在布尔
、数字
和字符串
构造函数中时,它们将成为对象。instanceof
运算符仅适用于对象(这就是它返回false
基本值的原因):
正如您所见,typeof
和instanceof
都不足以测试值是布尔值、数字还是字符串-typeof
仅适用于原始布尔值、数字和字符串;而instanceof
不适用于原始布尔、数字和字符串
幸运的是,这个问题有一个简单的解决方案。toString
的默认实现(即在Object.prototype.toString
上本机定义的)返回基本值和对象的内部[[Class]]
属性:
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
值的内部[[Class]]
属性比值的类型有用得多。我们可以使用Object.prototype.toString
创建自己(更有用)的typeof
操作符,如下所示:
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]
希望这篇文章有帮助。要了解原语和包装对象之间的差异,请阅读以下博文:对我来说
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
所以“str”istanceof String
应该返回true
,因为istanceof的工作原理如下:
"str".__proto__ // #1
=> String
表达式#1和#2的结果相互冲突,因此应该有一个错误
#1是错误的
我发现它是由\uuuu proto\uuuu
引起的,是非标准属性,所以使用标准属性:Object.getPrototypeOf
"str".__proto__ == String.prototype // #2
=> true
现在表达式#2和#3之间没有混淆,我相信我已经找到了一个可行的解决方案:
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
您可以使用这个,它将适用于这两种情况
var text=“foo”代码>//typeof将起作用
String text=新字符串(“foo”)代码>//instanceof将工作
这在ECMAScript规范中定义:如果类型(O)不是对象,则返回false。
换句话说,如果Obj instanceof Callable
中的Obj
不是对象,那么instanceof
将直接短路到false
。基本包装类型是引用类型,每当字符串、数字或布尔值出现时,都会在后台自动创建
已阅读。例如:
typeof(text) === 'string' || text instanceof String;
这就是幕后发生的事情:
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
因为第二行像对象一样使用字符串(原语),
JavaScript引擎创建一个String实例,以便charAt(0)将
String对象在销毁之前只存在于一条语句中
检查
instanceof运算符返回false,因为临时对象是空的
仅在读取值时创建。因为instanceof实际上并没有读取
任何东西,都不会创建临时对象,它告诉我们值不是
基本包装类型的实例。您可以创建基本包装器
手动键入注意,当测试变量时,这种技术在某些情况下可能会失败。在上面的示例中,String
和Boolean
前面有一个对当前窗口的隐式引用,因此,如果您正在测试在另一个窗口(如弹出窗口或框架)中创建的字符串变量的构造函数
属性,它将不等于简单的String
,它将等于thatOtherWindowsName.String
。并且不处理此问题并返回相应的布尔结果?如果传递了字符串的后代,则此操作将失败。@MichaelMathews:这可以解决以下问题:Object.prototype.toString.call('foo')='[对象字符串]“
@BryanLarsen和@MichaelMathews使用d.constructor==String
有什么问题吗?”?例如,使用一个松散的相等运算符。顺便说一句,我发现了一些较短的内容。函数isString(s){return s.constructor==String;}
Wor
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
typeof(text) === 'string' || text instanceof String;
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);