构造原型

课后整理 2020-12-10

直接使用prototype原型设计类的继承存在两个问题:

【示例1】简单定义Book类型,然后实例化。

function Book(){ }                                    //声明构造函数 
Book.prototype.o = {x:1,y:2}                     //构造函数的原型属性o是一个对象 
var book1 = new Book();                           //实例化对象book1
var book2 = new Book();                           //实例化对象book2
console.log(book1.o.x);                             //返回1
console.log(book2.o.x);                             //返回1
book2.o.x = 3;                                          //修改实例化对象book2中的属性x的值 
console.log(book1.o.x);                             //返回3
console.log(book2.o.x);                             //返回3

由于原型属性o为一个引用型的值,因此所有实例的属性o的值都是同一个对象的引用,一旦o的值发生变化,将会影响所有实例。

构造原型正是为了解决原型模式而诞生的一种混合设计模式,它把构造函数模式与原型模式混合使用,从而避免了此类问题的发生。

实现方法:对于可能会相互影响的原型属性,并且希望动态传递参数的属性,把它们独立出来使用构造函数模式进行设计。对于不需要个性设计、具有共性的方法或属性,则使用原型模式来设计。

【示例2】遵循上述设计原则,把其中两个属性设计为构造函数模式,设计方法为原型模式。

function Book(title,pages){                        //构造函数模式设计 
    this.title = title;
    this.pages = pages; 
}
Book.prototype.what = function(){             //原型模式设计 
    console.log(this.title  +this.pages);
};
var book1 = new Book("JavaScript程序设计",160);
var book2 = new Book("C程序设计",240);
console.log(book1.title);
console.log(book2.title);

构造原型模式是ECMAScript定义类的推荐标准。一般建议使用构造函数模式定义所有属性,使用原型模式定义所有方法。这样所有方法都只创建一次,而每个实例都能够根据需要设置属性值。这也是使用最广的一种设计模式。