instanceof
运算符应该查看原型,不是吗?在对象的原型发生变化后,为什么不改变它的答案?示例如下:
// The .prototype of objects created with 'new MyKlass'
// is MyKlass.prototype
var MyKlass = function(name, age) {
this.name = name;
this.age = age;
}
var xx = new MyKlass('xx', 20);
console.log(xx instanceof MyKlass); // true, OK
xx.prototype = new String('s');
console.log(xx instanceof MyKlass); // also true, WHY???
答案 0 :(得分:9)
本案例解释为in the MDN:
请注意,如果instanceof测试的值可以根据更改而改变 更改构造函数的prototype属性,它不可能 通过更改对象原型来改变,因为更改了对象 原型在标准ECMAScript中是不可能的。但是,可以使用非标准
__proto__
伪属性
这会记录错误:
xx.constructor.prototype = new String('s');
console.log(xx instanceof MyKlass);
简而言之,您不应该尝试改变JavaScript对象,它们不是设计为可变的。我不知道你的用例是什么,但可能有一个更好的解决方案,无论是组合,内部状态还是别的什么。
答案 1 :(得分:3)
它不是.prototype
而是[[原型]],或某些浏览器中可用的.__proto__
xx.__proto__ = new String("s");
console.log(xx instanceof MyKlass);
//false
console.log(xx instanceof String);
//true
将.prototype
属性分配给非函数除了正常分配任何普通属性外没有任何效果。对于仅在instanceof
检查中使用该函数或使用new
调用该函数时才有效的函数。
答案 2 :(得分:3)
instanceof运算符应该查看原型,不是吗?
是的,确实如此。请参阅MDN docs。
为什么在对象的原型发生变化后它没有改变答案?
var xx = new MyKlass('xx', 20); xx.prototype = new String('s');
因为您没有更改xx
对象的原型,但给它一个prototype
属性。 Object.getPrototypeOf(xx) === MyKlass.prototype
仍适用。有关详细信息,请参阅__proto__ VS. prototype in JavaScript。什么会起作用:
MyKlass.prototype = {}; // overwrite with a different object
console.log(xx instanceof MyKlass); // false now, xx doesn't inherit from the {}
或
xx.__proto__ = String.prototype; // or something
console.log(xx instanceof MyKlass); // false now, xx doesn't inherit from MyKlass.prototype
请注意,通过__proto__
写入内部[[prototype]]在ES5中是非标准的