"instanceof" of a String object vs that of "string" literals String对象的"instanceof"与"string"字面值的"instanceof"的区别

15 浏览
0 Comments

"instanceof" of a String object vs that of "string" literals String对象的"instanceof"与"string"字面值的"instanceof"的区别

"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中都是一样的。所以,至少是一致的。

0
0 Comments

在JavaScript中,除了原始值(布尔值、null、数字、字符串和undefined)之外,一切都是对象(或者至少可以被视为对象)。如下代码示例所示,对象、数组和null值都被视为对象,而函数被视为一种特殊类型的可调用对象:

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

需要注意的是,虽然函数被认为是一种特殊类型的对象,但它们仍然是对象。另一方面,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

希望本文对您有所帮助。如果想了解原始值和包装对象之间的区别,请阅读以下博文:The Secret Life of JavaScript Primitives

0
0 Comments

在Javascript中,原始类型与在Javascript中创建的对象是不同的类型。从Mozilla API文档中可以看到,可以使用instanceof操作符来判断一个对象是否是某个特定类型的实例。例如,下面的代码可以判断一个对象是否是String类型的实例:

var color1 = new String("green");
color1 instanceof String; // 返回true
var color2 = "coral";
color2 instanceof String; // 返回false(color2不是一个String对象)

然而,对于原始类型的判断,由于无法使用代码构造原始类型的实例,所以无法使用instanceof操作符。这可能就是为什么人们使用typeof "foo" === "string"而不是instanceof的原因。

另一个使用typeof而不是instanceof的原因是,typeof测试可以在来自其他框架或窗口的字符串上仍然有效,或者在String构造函数被重写的情况下仍然有效。

另外,可以使用+' '将String对象转换为字符串字面量的形式,例如(new String('green') + '') instanceof String将返回false。

需要注意的是,typeof foo === 'string'并不足够,可以使用Object.prototype.toString.call(foo)来进行更准确的判断。

总之,Javascript在处理字符串字面量与String对象时存在一些不一致和令人困惑的地方。原始类型与对象表示之间的区别是其中一个原因,另一个原因是instanceof操作符无法对原始类型进行判断。这可能是Javascript设计上的一些不一致之处。

0