此方法并非筆者原創,筆者隻是在前輩的基礎上,加以總結,得出一種簡潔實用的JavaScript繼承方法。
傳統的JavaScript繼承基于prototype原型鍊,并且需要使用大量的new操作,代碼不夠簡潔,可讀性也不是很強,貌似還容易受到原型鍊污染。
筆者總結的繼承方式,簡潔明了,雖然不是最好的方式,但希望能給讀者帶來啟發。
好了,廢話不多說,直接看代碼,注釋詳盡,一看就懂~~~
1 /**
2 * Created by 楊元 on 14-11-11.
3 * 不使用prototype實作繼承
4 *
5 */
6
7 /**
8 * Javascript對象複制,僅複制一層,且僅複制function屬性,不通用!
9 * @param obj 要複制的對象
10 * @returns Object
11 */
12 Object.prototype.clone = function(){
13 var _s = this,
14 newObj = {};
15 _s.each(function(key, value){
16 if(Object.prototype.toString.call(value) === "[object Function]"){
17 newObj[key] = value;
18 }
19 });
20 return newObj;
21 };
22
23 /**
24 * 周遊obj所有自身屬性
25 *
26 * @param callback 回調函數。回調時會包含兩個參數: key 屬性名,value 屬性值
27 */
28 Object.prototype.each = function(callback){
29 var key = "",
30 _this = this;
31 for (key in _this){
32 if(Object.prototype.hasOwnProperty.call(_this, key)){
33 callback(key, _this[key]);
34 }
35 }
36 };
37
38 /**
39 * 建立子類
40 * @param ext obj,包含需要重寫或擴充的方法。
41 * @returns Object
42 */
43 Object.prototype.extend = function(ext){
44 var child = this.clone();
45 ext.each(function(key, value){
46 child[key] = value;
47 });
48 return child;
49 };
50
51 /**
52 * 建立對象(執行個體)
53 * @param arguments 可接受任意數量參數,作為構造器參數清單
54 * @returns Object
55 */
56 Object.prototype.create = function(){
57 var obj = this.clone();
58 if(obj.construct){
59 obj.construct.apply(obj, arguments);
60 }
61 return obj;
62 };
63
64
65 /**
66 * Useage Example
67 * 使用此種方式繼承,避免了繁瑣的prototype和new。
68 * 但是目前筆者寫的這段示例,隻能繼承父類的function(可以了解為成員方法)。
69 * 如果想繼承更豐富的内容,請完善clone方法。
70 *
71 *
72 */
73
74 /**
75 * 動物(父類)
76 * @type {{construct: construct, eat: eat}}
77 */
78 var Animal = {
79 construct: function(name){
80 this.name = name;
81 },
82 eat: function(){
83 console.log("My name is "+this.name+". I can eat!");
84 }
85 };
86
87 /**
88 * 鳥(子類)
89 * 鳥類重寫了父類eat方法,并擴充出fly方法
90 * @type {子類|void}
91 */
92 var Bird = Animal.extend({
93 eat: function(food){
94 console.log("My name is "+this.name+". I can eat "+food+"!");
95 },
96 fly: function(){
97 console.log("I can fly!");
98 }
99 });
100
101 /**
102 * 建立鳥類執行個體
103 * @type {Jim}
104 */
105 var birdJim = Bird.create("Jim"),
106 birdTom = Bird.create("Tom");
107
108 birdJim.eat("worm"); //My name is Jim. I can eat worm!
109 birdJim.fly(); //I can fly!
110
111 birdTom.eat("rice"); //My name is Tom. I can eat rice!
112 birdTom.fly(); //I can fly!