313
"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 中也是如此。所以,至少它是一致的。

4

10 回答 10

479

基元是一种不同于从 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 都会做另一件事。

于 2008-10-15T04:54:52.020 回答
118

我用:

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

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

于 2011-10-14T19:38:48.857 回答
70

在 JavaScript 中,一切都是对象(或者至少可以被视为对象),除了基本类型(布尔值、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和不是对象。它们是 JavaScript 中的原始值。然而,布尔值、数字和字符串也有构造函数,它们分别包装各自的原语以提供附加功能:0""undefinedBooleanNumberString

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

正如您所看到的,当原始值分别包含在Boolean,NumberString构造函数中时,它们分别成为对象。该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不足以测试一个值是布尔值、数字还是字符串 -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 原语的秘密生活

于 2013-08-05T11:35:25.690 回答
39

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

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
于 2009-07-26T23:10:50.880 回答
13
 typeof(text) === 'string' || text instanceof String; 

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

  1. var text="foo"; // typeof 会起作用

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

于 2017-08-23T10:33:53.250 回答
3

这在 ECMAScript 规范第 7.3.19 步第 3 节中定义:If Type(O) is not Object, return false.

换句话说,如果ObjinObj instanceof Callable不是一个对象,instanceof就会直接短路到false

于 2019-06-18T19:29:31.987 回答
1

我相信我已经提出了一个可行的解决方案:

Object.getPrototypeOf('test') === String.prototype    //true
Object.getPrototypeOf(1) === String.prototype         //false
于 2017-03-17T23:19:39.113 回答
1

原始包装类型是在读取字符串、数字或布尔值时在后台自动创建的引用类型。例如:

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) 可以工作。String 对象在它被销毁之前只存在一个语句检查这个

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

于 2021-02-15T18:27:09.553 回答
-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之间没有混淆

于 2015-01-12T09:59:50.023 回答
-8

或者您可以像这样制作自己的功能:

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

用法:

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

这些都应该返回true。

于 2010-02-16T16:54:35.380 回答