原型模式
当直接创建对象的代价比较大时,可以通过复制一个现有的对象生成新的对象,就叫做原型模式。
当然,JavaScript 本身就是基于原型实现继承的(1),因此在 JavaScript 中使用原型模式非常简单。
值得注意的是,JavaScript 原型上的成员(属性和方法)是所有实例共享的,并非定义中的复制。
*(1)有关于原型继承的内容,此前已经说过很多了,可以参考最新的一篇手记:面向对象之继承性
例子:
/* 基类 */
function F_class(name, age) {
this.name = name;
this.age = age;
};
//基类原型
F_class.prototype = {
getName: function () {
return this.name;
},
getAge: function () {
return this.age;
}
}
/* 子类 */
function C_class() {
F_class.apply(this, arguments);
}
//子类原型(通过继承基类原型)
C_class.prototype = new F_class();
/* 创建子类实例 */
var p = new C_class("Tom", 20);
console.log(p.getName());
//输出 Tom
将那些可复用的、可共享的、耗时大的放到基类的原型中,然后子类通过组合式继承或者其他继承方式,将基类原型中的成员继承下来,这样由子类创建的对象也就共享了基类中的属性和方法。
重写原型成员
对于子类差异化的需求,子类可以通过重写基类的成员来解决。
例子:
/* 基类 */
function F_class(name, age) {
this.name = name;
this.age = age;
};
//基类原型
F_class.prototype = {
getName: function () {
return this.name;
},
getAge: function () {
return this.age;
}
}
/* 子类 */
function C_class() {
F_class.apply(this, arguments);
}
//子类原型(通过继承基类原型)
C_class.prototype = new F_class();
//重写基类方法
C_class.prototype.getName = function () {
var name_list = this.name.split(" ");
return "firstName:" + name_list[0] + "/" + "lastName:" + name_list[1];
}
/* 创建子类实例 */
var p = new C_class("Brown Tom", 20);
console.log(p.getName());
//输出 firstName:Brown/lastName:Tom
拓展原型成员
基类原型是一个共享的对象,因此对基类原型的拓展,无论是基类的实例,还是子类的实例,都可以继承下来。
例子:
/* 基类 */
function F_class(name, age) {
this.name = name;
this.age = age;
};
//基类原型
F_class.prototype = {
getName: function () {
return this.name;
},
getAge: function () {
return this.age;
}
}
/* 子类 */
function C_class() {
F_class.apply(this, arguments);
}
//子类原型(通过继承基类原型)
C_class.prototype = new F_class();
//基类拓展一个 getJob 方法
F_class.prototype.getJob = function () {
return "Web Worker";
}
/* 创建子类实例 */
var p = new C_class("Tom", 20);
console.log(p.getJob());
//输出 Web Worker
原型共享给予我们拓展的自由性,但也有可能会影响到他人,因此要谨慎使用。
如有错误,欢迎指正,本人不胜感激。