为什么以下两行返回不同的结果?
("test" instanceof String) // returns false
("test".constructor == String) // returns true
在 chrome 版本 28.0.1500.95 m 的控制台中测试
对于本机类型,它的工作方式是否略有不同?
为什么以下两行返回不同的结果?
("test" instanceof String) // returns false
("test".constructor == String) // returns true
在 chrome 版本 28.0.1500.95 m 的控制台中测试
对于本机类型,它的工作方式是否略有不同?
constructor
只是内部[[prototype]]
属性的一个属性,可以很容易地操纵:
function A(){}
function B(){}
A.prototype.constructor = B;
var a = new A();
console.log(a.constructor); //B
然而,instanceof
操作员检查内部原型链并且不容易被愚弄,即使您更改prototype
了构造函数的完整属性:
function A(){}
function B(){}
A.prototype = B.prototype;
var a = new A();
console.log(a instanceof A); //true
console.log(a instanceof B); //false
那么,为什么是"test" instanceof String === false
但是("test".constructor == String) === true
?
首先,"test"
是原语,原语永远不是任何事物的实例。使用时实际发生的是构造函数instanceof
的内部[[HasInstance]]
方法以可能的实例作为参数调用。所以a instanceof A
大致翻译为:
`A.[[HasInstance]](a)`
ECMA 规范有这样的说法[[HasInstance]]
: http: //www.ecma-international.org/ecma-262/5.1/#sec-15.3.5.3
[[HasInstance]] (V)
假设 F 是一个 Function 对象。
当 F 的 [[HasInstance]] 内部方法以值 V 被调用时,采取以下步骤:
- 如果 V 不是对象,则返回 false。
- ……
换句话说:如果左侧instanceof
不是对象,则运算符将返回false。
("test".constructor == String) === true
出于不同的原因:如果您尝试访问原语的属性,该原语将临时转换为对象。所以"test".constructor
大致等于:
(new String("test")).constructor
在这种情况下,您实际上是在使用构造函数创建一个对象,然后再请求该constructor
属性。因此,它会返回也就不足为奇了String
。
主要区别在于instanceof
检查对象的原型链,而检查构造函数只检查它是否是从同一个构造函数创建的。
例子:
function MyObject() {
this.sayHi = function() { alert('Hi!'); }
}
var x = new MyObject();
alert(x.constructor === Object);
alert(x instanceof Object);