更深層次的類的創建
Turing的方法Class.create方法創建一個類,使用new創建的過程中會調用初始化方法。方法非常簡單: create: function() {
var methods = null,
parent = undefined,
klass = function() {
this.initialize.apply(this, arguments);
};
apply看上去很神奇,但是有些人不太喜歡他,因爲它使用複雜不利於封裝。上面的例子,我們在類的構造函數中調用初始化方法,並使用this和arguments作爲參數。this表示將方法綁定到新創建的實例上執行,arguments代表你給構造函數傳遞的所有參數。
根據上面的代碼,所有的創建的類都應該有一個默認的初始化方法。如果你不需要在初始化的時候做什麼,你可以定義一個簡單的空方法:
if (!klass.prototype.initialize)
klass.prototype.initialize = function(){};
語法技巧
在我們的類裏繼承其他對象是一個非常有用的技巧。語法如下:var MixinUser = turing.Class({
include: User,
initialize: function(log) {
this.log = log;
}
});
引入對象應該遵守一定的規則,以便讓代碼有一個統一的規範。
- 方法必須從指定的類裏繼承
- initialize方法不能被覆蓋
- 可以繼承多個對象
mixin: function(klass, things) {
if "there are some valid things" {
if "the things are a class" {
"use turing.oo.extend to copy the methods over"
} else if "the things are an array" {
for "each class in the array" {
"use turing.oo.extend to copy the methods over"
}
}
}
},
父類
之前我們提到了Prototype的super功能。Prototype允許類通過addMethods擴展方法,相同名稱的方法會被覆蓋,但是我們仍然可以通過$super來方法父類的方法。下面的例子,我們創建了User類,並且通過繼承User類創建了SuperUser:
var User = turing.Class({
initialize: function(name, age) {
this.name = name;
this.age = age;
},
login: function() {
return true;
},
toString: function() {
return "name: " + this.name + ", age: " + this.age;
}
});
var SuperUser = turing.Class(User, {
initialize: function() {
// Somehow call the parent's initialize
}
});
我們測試上面的代碼:
given('an inherited class that uses super', function() {
var superUser = new SuperUser('alex', 104);
should('have run super()', superUser.age).equals(104);
});
我們還沒有實現super,執行結果如下:
Given an inherited class that uses super
- should have run super(): 104 does not equal: undefined
上面的代碼說明新的初始化方法覆蓋了父類的方法。現在我們想要調用父類的初始化方法,這裏再次使用了apply。
var SuperUser = turing.Class(User, {
initialize: function() {
User.prototype.initialize.apply(this, arguments);
}
});
代碼看上去還不太完美,許多語言的super的實現都比較簡單,讓用戶通過apply來實現super的調用確實不太友好。最好的辦法就是在父類的原型中實現super方法,把上面的代碼封裝起來。
var SuperUser = turing.Class(User, {
initialize: function() {
this.$super('initialize', arguments);
},
toString: function() {
return "SuperUser: " + this.$super('toString');
}
});
這樣的代碼看上去簡單多了並且便於理解。
結論
我們現在已經實現了一個簡單,可讀的面向對象的類。我們以後的架構都是基於這個類實現的。我希望通過最近的兩篇文章,能讓你感受到js的簡單和靈活。