`this instanceof String`和``foo“instanceof String`有什么区别?

时间:2014-03-03 21:08:02

标签: javascript

我正在扩展像这样的对象:

Object.prototype.is_a = function (x) {
  return this instanceof x;
}

一切按预期工作

"foo".is_a(String) // true
"foo".is_a(Object) // true
"foo".is_a(Array) // false
"foo".is_a(Function) // false
"foo".is_a(Boolean) // false
"foo".is_a(Date) // false
"foo".is_a(Number) // false
"foo".is_a(RegExp) // false

但是,

"foo" instanceof String // false
this功能上的

is_a()关键字与foo相同吗?为什么它会返回不同的结果?

4 个答案:

答案 0 :(得分:10)

首先,您无法将instanceof应用于原始值,这就是

的原因
"foo" instanceof String

返回false。基元不是对象,因此不能是构造函数的实例。 *

那为什么它似乎在is_a方法中有用?

在非严格模式下,函数is always going to be an object内的this值(步骤3)。如果this值不是对象,则将其隐式转换为1。您可以使用console.log(typeof this)进行测试 这意味着字符串原语"foo"将转换为String对象new String("foo"),这就是您可以在其上使用instanceof的原因。

在严格模式下,this的值不必是对象,也不会自动转换(step 1)。在这种情况下,你的方法会失败:

> Object.prototype.is_a = function (x) {
   'use strict';
   return this instanceof x;
 }
> "foo".is_a(String)
false

*:这是一个非常简化的解释。实际上,instanceof运算符将评估委托给构造函数的内部[[HasInstance]] method,如果传递的值不是对象,则将其定义为返回false

答案 1 :(得分:1)

字符串文字与String对象(MDN)不同。看起来字符串文字(字符串基元)在用作函数的绑定上下文时(即在函数内部this时)会自动装入对象中:

>>> typeof "foo"
"string"
>>> Object.prototype.type_of = function (x) {
  return typeof this;
}
function (x) {
  return typeof this;
}
>>> "foo".type_of()
"object"

这也解释了你的行为实例。这表现得如你所料:

>>> new String("foo") instanceof String
true
>>> new String("foo") instanceof Object
true
>>> new String("foo").is_a(String)
true
>>> new String("foo").is_a(Object)
true
>>> new String("foo").is_a(Array)
false

答案 2 :(得分:1)

JavaScript包含字符串,数字和布尔值的原始版本和对象版本。字符串文字定义基元而不是对象。如果你做typeof "foo",你会得到“字符串”而不是“对象”。但是当你访问字符串的属性时,它会从原始字符串创建一个临时的String对象,然后访问该对象的相应属性,因此this instanceof String在临时字符串中是真的对象的方法。

为了在考虑基元和对象的同时测试某些东西是否为字符串,您需要测试typeof foo === "string" || foo instanceof String

答案 3 :(得分:0)

instanceof需要定义一个对象,此示例返回true:

var f = new String("foo");
alert( f instanceof String);

这与您的示例更相似:

alert( new String("foo") instanceof String);