在 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
""
undefined
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 原语的秘密生活