扫码关注官方订阅号
这里只是进行了原型的重写,并没有对构造器进行重写。不太明白浏览器给出的除了第三个之外的其余四个布尔值答案。。请大神帮我看看。。给我解答下。。谢谢。。
认证高级PHP讲师
function MyObject(){}//[1] var obj1=new MyObject();//[2] console.log('[2]'+(obj1 instanceof MyObject));//true console.log(obj1.__proto__===MyObject.prototype);//true MyObject.prototype.type='MyObject';//[3] var obj2=new MyObject();//[4] console.log('[4]'+(obj2 instanceof MyObject));//true MyObject.prototype={//[5] type:"Bird" } var obj3=new MyObject();//[6] console.log('[6]'+(obj3 instanceof MyObject));//true console.log(obj1 instanceof MyObject);//[7] false console.log(obj2 instanceof MyObject);//[8] false console.log(obj3 instanceof MyObject);//[9] true console.log(obj1 instanceof obj1.constructor);//[10] false console.log(obj1.constructor ===MyObject);//[11] true
instanceof的操作语义为判断操作符左边的实例对象的原型链中是否存在操作符右边的构造函数的prototype属性指向的对象-也就是原型对象JS实现引擎,会为每一个对象添加一个__proto__自有属性,指向这个对象的原型对象
instanceof
__proto__
执行[2]后,obj1的原型链中存在MyObject.prototype指向的对象-一个Object类型的实例对象PROTOTYPE_ORG,其constructor属性值为MyObject函数,obj1.__proto__属性指向MyObject.prototype指向的对象,也就是obj1.__proto__和PROTOTYPE_ORG相同[3]只是为原型对象添加了一个属性,并没有改变原MyObject.prototype属性指向的对象,obj1和obj2的原型链是相同的[5]来了个大的,把MyObject.prototype的默认指向改变了,指向了一个新的对象PROTOTYPE_NEW,这个对象带有一个type属性,并且这个对象的constructor为Object(默认构造函数)。那么此时PROTOTYPE_NEW和PROTOTYPE_ORG同时存在;obj1和obj2的__proto__属性还是指向的PROTOTYPE_ORG。这个和下面代码的处理方式同理:
PROTOTYPE_ORG
PROTOTYPE_NEW
var a1={ name:"a1" }; var b1=a1; console.log(a1.name);//a1 console.log(b1.name);//a1 b1={ name:"b1" }; console.log(a1.name);//a1 console.log(b1.name);//b1
[6]创建的obj3的原型指向新的原型对象7 PROTOTYPE_NEW和PROTOTYPE_ORG是2个不同的对象[10] obj1.constructor为MyObject,MyObject的prototype现在指向PROTOTYPE_NEW,而obj1.__proto__指向PROTOTYPE_ORG[11] obj1.constructor为MyObject
这张图又派上用场了:
这是你对prototype,constructor没有理解的缘故。前两个false,是由于你对prototype进行了改写,所以为false.第三个,你重新new的,自然而然是true.第四个false,其实和前两个一样,解释参考第五个true第五个true,因为constructor指向的就是构造器。
这里所说的构造器,不要和Java之类的面向对象的构造器搞混了,是有一些区别的。
再补充一点,对于instanceof方法,也可能会造成误解,提供一篇资料说明:http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/
注意instanceof为一个独立的方法,跟你MyObject没有任何关系的,重点在这里:
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式 var O = R.prototype;// 取 R 的显示原型 L = L.__proto__;// 取 L 的隐式原型 while (true) { if (L === null) return false; if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true return true; L = L.__proto__; } }
你对prototype的更改,引用(指向,指针)是没有发生变化的。
你重写prototype那句,相当于下面这样,
MyObject.prototype = { constructor: Object, type: 'Bird' }
constructor 同时被覆盖,所以前两个是false,第三个是新的,obj3.constructor 等于 Object,和MyObject.prototype.constructor相同,所以true
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
instanceof的操作语义为判断操作符左边的实例对象的原型链中是否存在操作符右边的构造函数的prototype属性指向的对象-也就是原型对象JS实现引擎,会为每一个对象添加一个
__proto__自有属性,指向这个对象的原型对象执行[2]后,obj1的原型链中存在MyObject.prototype指向的对象-一个Object类型的实例对象
PROTOTYPE_ORG,其constructor属性值为MyObject函数,obj1.__proto__属性指向MyObject.prototype指向的对象,也就是obj1.__proto__和PROTOTYPE_ORG相同[3]只是为原型对象添加了一个属性,并没有改变原MyObject.prototype属性指向的对象,obj1和obj2的原型链是相同的
[5]来了个大的,把MyObject.prototype的默认指向改变了,指向了一个新的对象
PROTOTYPE_NEW,这个对象带有一个type属性,并且这个对象的constructor为Object(默认构造函数)。那么此时PROTOTYPE_NEW和PROTOTYPE_ORG同时存在;obj1和obj2的__proto__属性还是指向的PROTOTYPE_ORG。这个和下面代码的处理方式同理:[6]创建的obj3的原型指向新的原型对象
7
PROTOTYPE_NEW和PROTOTYPE_ORG是2个不同的对象[10] obj1.constructor为MyObject,MyObject的prototype现在指向
PROTOTYPE_NEW,而obj1.__proto__指向PROTOTYPE_ORG[11] obj1.constructor为MyObject
这张图又派上用场了:

这是你对prototype,constructor没有理解的缘故。
前两个false,是由于你对prototype进行了改写,所以为false.
第三个,你重新new的,自然而然是true.
第四个false,其实和前两个一样,解释参考第五个true
第五个true,因为constructor指向的就是构造器。
这里所说的构造器,不要和Java之类的面向对象的构造器搞混了,是有一些区别的。
再补充一点,对于instanceof方法,也可能会造成误解,提供一篇资料说明:
http://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/
注意instanceof为一个独立的方法,跟你MyObject没有任何关系的,重点在这里:
你对prototype的更改,引用(指向,指针)是没有发生变化的。
你重写prototype那句,相当于下面这样,
constructor 同时被覆盖,所以前两个是false,
第三个是新的,obj3.constructor 等于 Object,和MyObject.prototype.constructor相同,所以true