JS中的原型对象(二)

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

重写原型对象

请看下例:

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);         //true
alert(Amy instanceof Person);         //true
alert(Amy.constructor == Person);     //false
alert(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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值