为什么 instanceof 对于某些文字返回 false?

问题描述 投票:0回答:11
"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

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

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

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

FF3、IE7、Opera、Chrome 中也是如此。所以,至少它是一致的。

javascript literals instanceof
11个回答
509
投票

原语是一种与 Javascript 中创建的对象不同的类型。来自 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)

我找不到任何用代码构造原始类型的方法,也许这是不可能的。这可能就是为什么人们使用

typeof "foo" === "string"
而不是
instanceof

记住此类事情的一个简单方法是问自己“我想知道什么是明智且易于学习的”?无论答案是什么,Javascript 都会做另一件事。


124
投票

我用:

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

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


75
投票

在 JavaScript 中,一切都是对象(或者至少可以被视为对象),除了 primitives(布尔值、null、数字、字符串和值

undefined
(以及 ES6 中的符号)):

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
是对不存在的对象的引用)。函数之所以与众不同,是因为它们是一种特殊类型的“可调用”对象。然而它们仍然是物体。 另一方面,文字

true

0
""
undefined
不是对象。它们是 JavaScript 中的原始值。然而,布尔值、数字和字符串也分别具有构造函数
Boolean
Number
String
,它们包装各自的原语以提供附加功能:

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
都不足以测试一个值是布尔值、数字还是字符串 -
typeof
仅适用于原始布尔值、数字和字符串;并且
instanceof
不适用于原始布尔值、数字和字符串。

幸运的是,这个问题有一个简单的解决方案。

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]]

属性比值的

typeof
有用得多。我们可以使用
Object.prototype.toString
创建我们自己的(更有用)版本的
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 基元的秘密生活


43
投票

'foo'.constructor == String // returns true true.constructor == Boolean // returns true



18
投票
你可以使用这个,它适用于两种情况

  1. var text="foo";

    // typeof 可以工作

    
    

  2. String text= new String("foo");

    // instanceof 可以工作

    
    


3
投票
第 7.3.19 节第 3 步

中定义的:If Type(O) is not Object, return false.


也就是说,如果

Obj

中的

Obj instanceof Callable
不是一个物体,
instanceof
会直接短路到
false
    


2
投票

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



2
投票

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);

因为第二行像对象一样使用字符串(原语),
JavaScript 引擎创建一个 String 实例,以便 charAt(0) 将
work.String 对象在被销毁之前仅存在于一条语句中
检查
这个

instanceof

运算符返回 false,因为临时对象是 仅在读取值时创建。因为instanceof实际上并没有读取 任何东西,都没有创建临时对象,它告诉我们这些值不是 原始包装类型的实例。您可以创建原始包装器 手动输入


0
投票
instanceof

来检查

constructor
的值,如下所示:
const checkIsInstanceOf = (value, instance) => value.constructor === instance;

console.log(checkIsInstanceOf(5, Number)); // true
console.log(checkIsInstanceOf(5, String)); // false
console.log(checkIsInstanceOf(new Date(), Function)); // false
console.log(checkIsInstanceOf("Reza", String)); // true



-2
投票

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

所以 
"str" istanceof String

应该返回

true
因为 istanceof 的工作原理如下:

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

表达式
#1

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

#1 错了

我发现它是由

__proto__

引起的,是非标准属性,所以使用标准属性:

Object.getPrototypeOf

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

现在表达式 
#2

#3 之间不再混淆


-8
投票

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

用途:

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

这些都应该返回 true。

© www.soinside.com 2019 - 2024. All rights reserved.