JS中的原型对象(二)

来源:互联网 发布:用友软件 t系列 编辑:程序博客网 时间:2024/06/05 12:00

本篇介绍重写原型对象的原理及对实例的影响;原型对象的问题

重写原型对象

请看下例:

function Person(){}var Edward = new Person();Person.prototype.name = "Sheldon";Person.Prototype.age = 29;Person.prototype.job = "Physical Scientist";Person.prototype.sayName = function(){    alert(this.name);};Edward.sayName ();            //"Sheldon"(没有问题)

在上例中,每添加一个属性或方法就要输入一遍 Person.prototype ,为了简化,更常见的做法是用一个新的对象字面量来重写原型,如:

function Person(){}Person.prototype = {    name : "Sheldon",    age : 29,    job : "Physical Scientist",    sayName : function(){        alert(this.name);    }};

在上例中, Person.prototype 实质上被设置成了一个新对象,这个新对象自动获得的新的 constructor 属性也不再指向 Person 函数。尽管 instanceof 操作符还能返回正确的结果,但通过 constructor 已无法正确确定对象类型了。

var Amy = new Person();alert(Amy instanceof Object);         //truealert(Amy instanceof Person);         //truealert(Amy.constructor == Person);     //falsealert(Amy.constructor == Object);     //true

如果 constructor 值很重要,可以将它特意设置回适当的值,但这会导致它的 Enumerable 特性被设置为 true

function Person(){}Person.prototype = {    constructor : Person,    name : "Sheldon",    age : 29,    job : "Physical Scientist",    sayName : function(){        alert(this.name);    }};

原型的动态性

原型具有动态性,即当原型有修改时,无论实例在原型修改前创建还是修改后创建,原型修改的内容都可以在实例体现。

function Person(){}var Edward = new Person();Person.prototype.sayHello = function(){    alert("Hello");};Edward.sayName ();            //"Hello"(没有问题)

除了自定义类型,所有的原生引用类型(Object、Array、String,等等 )都采用这种模式。通过原生对象的原型,不仅可以获得所有默认方法的引用,也可以定义新方法。

重写原型之后,现有原型与之前已经存在的原型实例之间没有联系,它们引用的仍然是最初的原型。

function Person(){}var Edward = new Person();Person.prototype = {    sayHi : function(){        alert("Hi");    }};Edward.sayHi();          //Error

原型对象的问题

因为原型中的属性都被所有实例共享,因此,所有实例在默认情况下都将取得相同的属性值。如果原型中有包含引用值的属性,当修改某一实例的该属性时,这次的修改将同步至其他实例,这将导致问题的产生。如:

function Person(){}Person.prototype = {    constructor : Person,    name : "Sheldon",    age : 29,    job : "Physical Scientist",    friends : ["Amy","Edward","Penny"]    sayName : function(){        alert(this.name);    }};var person1= new Person();var person2 = new Person();person1.friends.push("John");alert(person1.friends);       //"Amy,Edward,Penny,John"alert(person2.friends);       //"Amy,Edward,Penny,John"alert(person1.friends == person2.friends)      //true

这正是很少有人单独使用原型模式的原因。

原创粉丝点击