对于每个构造函数来说,都有一个prototype属性。对于每个对象实例来说,都有_proto_属性。
参看下面代码:
function Person(){} Person.prototype={ name:"Mike", age:18, sayName:function(){ alert(this.name); } }; var friend = new Person(); alert(friend instanceof Person);//true alert(friend.constructor == Person);//false
alert(friend.constructor == Object);//true
由于重写了Person.prototype,friend.constructor不再指向Person了。这个问题可以通过在Person.prototype中添加constructor:Person来避免,但是这也会导致constructor变为可列举的属性。
参看下面代码:
function Person(){} var friend = new Person(); Person.prototype= {
constructor:Person, name:"Mike", age:18, sayName:function(){ alert(this.name); } };
调用friend.sayName()的结果是什么?
会报错。 为什么?
重写原型对象切断了现有原型与之前任何原型对象实例之间的联系。
参看下面的代码:
function Person(){} Person.prototype= { constructor:Person, name:"Mike". age:18; friends:["Tom","Rose"], sayName:function(){ alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van"); alert(person2.friends); alert(person1.friends==person2.friends);
原型对象中的引用类型的属性,对于每个实例来说也都是共享的。
类似问题在原型模式的继承中也会体现:
function SuperType(){ this.colors=["red","blue","green"]; } function SubType(){} SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors);//red,blue,green,black var instance2 = new SuperType(); alert(instance2.colors);//red,blue,green,black