JavaScript 完美繼承

我們知道,父類中的屬性有this、static和prototype三種。我們常用的繼承方式有兩種:

  1. 原型繼承:可以把父類的prototype屬性全部繼承下來
  2. 對象冒充:可以將父類的this屬性繼承下來,再配合for...in循環,可以將父類的static屬性也繼承下來

將這兩種方式綜合使用,並在此基礎上,使用delete刪除不需要的屬性,以及通過重寫方法來覆蓋父屬性,以達到完美繼承的效果。


/**
 * Filename: PrefectExtend.js
 * Description: 該程序將通過原型繼承、對象冒充和覆蓋三套機制,來完美實現
 * 	Js的繼承。
 * Date: 2012/3/7
 */

/**
 * 父類Animal,及其this、靜態、prototype屬性的構造。
 */
Animal = function(tail) {
	this.tail = tail || "動物的尾巴";	// 父類的this屬性
	this.kinds = "動物";
	Animal.instanceCounter ++;			// 父類的靜態屬性
}
Animal.instanceCounter = 0;
Animal.prototype = {					// 父類的prototype屬性
	happy: function() {
		console.log("搖動>" + this.tail);
	},
	eat: function() {
		console.log("動物吃生的");
	},
	run: function() {
		console.log("動物四條腿跑");
	},
	fight: function() {
		console.log("動物往死裏打");
	}
}
// 這裏如果不這樣做,那麼Animal.prototype.constructor == Object,詳見參考資料[2]
Animal.prototype.constructor = Animal;

/**
 * 1. 對象冒充: 繼承this及static屬性
 */
// 子類Person
Person = function(name) {
	Person.superclass.call(this);	// this屬性繼承
	delete this.tail; // 刪除不需要的this屬性
	this.name = name || "獵空de代碼";
	for(var p in Animal) {			// static屬性繼承
		Person[p] = Animal[p];
	}
}
Person.superclass = Animal;
/**
 * 2. 原型繼承
 */
F = function() {} // 空殼函數,用於清除Animal的構造屬性(this和靜態)
F.prototype = Animal.prototype;
Person.prototype = new F();
delete Person.prototype.fight;	//刪除不需要的prototype屬性
Person.prototype.constructor = Person;
/**
 * 3. prototype方法覆蓋
 */
Person.prototype.eat = function() {
	console.log(this.name + "吃熟的");
}

// 創建實例
var person = new Person();
console.log("姓名: " + person.name);
console.log(person.kinds);
console.log("實例數目" + Person.instanceCounter);
person.happy();
person.eat();
person.run();


程序運行結果:

參考資料:

[1]  Ext 江湖,大漠窮秋,北京:電子工業出版社,2012.1 (這段程序,基本是模仿該書寫的)

[2] JavaScript類和繼承:constructor屬性


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章