在 JavaScript 中,一切都是对象(或者至少可以被视为对象),除了基元(布尔值、空值、数字、字符串和值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 基元的秘密生活