|
2011/09/30 23:11
5月28日に、静岡Developers勉強会「第3回JavaScript読書会」を開催しました。
http://www.haskell.shizu-dev.org/
勉強会では、「JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス 」の本を使用しております。
今回のテーマは「5章 継承」でした。 継承パターンとして、「プロトタイプ型の継承」と「関数型の継承」の2パターンについて説明があります。
「プロトタイプ型の継承」については、一般的な方法であるため、すぐに調べることが出来たのですが、
「関数型の継承」については、この本の説明や検索しても少なくてすぐには理解しにくかったです。
特に「eventuality」の使用方法とか書いてないし、どうやって使うの?って状態でした。
■関数型の継承メリット
プロトタイプ型の継承は、オブジェクトのすべてのプロパティが外から丸見えで、プライベート変数やプライベートメソッドを利用することができない。
関数型の継承は、大きな柔軟性を持っておりカプセル化と情報隠蔽を行うことができ、継承元のメソッドへアクセスすることもできる。
下記のサイトを参考になんとかサンプルを作成してみました。
http://d.hatena.ne.jp/t_gaisho/20100731/p2
http://docs.komagata.org/4472
http://tech.actindi.net/3478908901
いいサンプルが思い浮かばず、お風呂に思いついた、身長と体重からBMIを計算する案に落ち着きました。
BMIは、体重 ÷ 身長の2乗 で求めることが出来ます。
今回、このBMIの計算部分を Private に、出力部分をPublicにしてみました。
var eventuality = function(that) {
var registry = {}
that.fire = function(event) {
var array, func, handler,
type = typeof event === 'string' ? event : event.type
if (registry.hasOwnProperty(type)) {
array = registry[type]
for (var i = 0; i < array.length; i++) {
handler = array[i]
func = handler.method
if (typeof func === 'string') {
func = this[func]
}
func.apply(this, handler.parameters || [event])
}
}
return this
}
that.on = function(type, method, parameters) {
var handler = {method: method, parameters: parameters}
if (registry,hasOwnProperty(type)) {
registry[type].push(handler)
} else {
registry[type] = [handler]
}
return this
}
return that
}
//Human classfunction human(spec,my) {
var that = eventuality({})
my = my || {}
my.bmi = -1
//Private Method
my.calc_bmi = function(){
h = spec.height / 100
my.bmi = Math.round(spec.weight / (h * h))
}
//Public Method
that.out_bmi = function() {
my.calc_bmi()
alert(spec.name + " BMI = " + my.bmi)
}
//Event Method
that.on('print', function(){
alert(spec.name + ' Height = ' + spec.height + ',Weight = ' + spec.weight);
});
return that
}
//Student classvar student = function(spec) {
var that = human(spec),
super_out = that.out_bmi;
that.out_bmi = function() {
super_out() // super class method }
return that
}
//Mainvar myHuman = human({name : 'hanako',height : 158,weight : 40})
myHuman.fire('print')
myHuman.out_bmi()
//myHuman.calc_bmi() //private method can not access
//humanを継承
var taro = student({name : 'taro',height : 175,weight : 60})
taro.fire('print')
taro.out_bmi()
|