オブジェクトの継承
継承元のオブジェクトのメソッド呼び出すこともできる。
superiorというメソッドを定義する。
このメソッドは、プロパティが上書きされていたとしてに、オリジナルのメソッドを呼び出すことができるようになっている。
このsuperiorメソッドはJavaScript The Good Partsに載っていた。
var mammal = function(spec) {
var that = {};
that.get_name = function() {
return spec.name;
};
that.says = function() {
return spec.saying || '';
};
return that;
};
var myMammal = mammal({
name: 'Herb'
});
var cat = function(spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.get_name = function(a) {
return that.says() + ' ' + a + ' ' + spec.name + ' ' + that.says();
};
return that;
};
Function.prototype.method = function(name, func) {
this.prototype[name] = func;
return this;
};
Object.method('superior', function(name) {
var that = this,
method2 = that[name];
return function() {
return method2.apply(that, arguments);
};
});
var coolcat2 = function(spec) {
var that = cat(spec),
super_get_name = that.superior('get_name');
that.get_name = function(n) {
return 'like ' + super_get_name(100) + ' baby';
};
return that;
};
var myCoolCat = coolcat2({
name: 'Bix'
});
var name = myCoolCat.get_name();
console.log(name);// like meow 100 Bix meow baby
superiorメソッドではなく、superior関数にすると次のようになる。
このsuperior関数はJavaScript The Good Partsに載っていない。
「superior関数は部分適用の手法を利用して新しい関数を生成している。」と言える。
これにより、superior関数は与えられたnameに対応するメソッドを保持しており、それを後から与えられた引数で呼び出すことができる新しい関数を返している。
部分適用の説明をしておく。
部分適用は、与えられた関数の一部の引数を固定して新しい関数を作成するプロセスを指す。
var mammal = function(spec) {
var that = {};
that.get_name = function() {
return spec.name;
};
that.says = function() {
return spec.saying || '';
};
return that;
};
var myMammal = mammal({
name: 'Herb'
});
var cat = function(spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.get_name = function(a) {
return that.says() + ' ' + a + ' ' + spec.name + ' ' + that.says();
};
return that;
};
var superior = function(name) {
var that = this,
method2 = that[name];
return function() {
return method2.apply(that, arguments);
};
}
var coolcat2 = function(spec) {
var that = cat(spec),
super_get_name = superior.call(that, 'get_name');
that.get_name = function(n) {
return 'like ' + super_get_name(100) + ' baby';
};
return that;
};
var myCoolCat = coolcat2({
name: 'Bix'
});
var name = myCoolCat.get_name();
console.log(name);// like meow 100 Bix meow baby
superiorメソッドではなく、superior関数にするのは、Function.prototypeを触るのは、あまりやりたくないからである。
Function.prototypeに追加すること自体は基本的に問題ない。ただし、いくつか注意点がある。
(1)名前の衝突: 既存のプロパティやメソッドと名前が衝突する可能性があるため、注意が必要である。
(2)他のコードとの互換性: 同じ名前を使った他のライブラリやコードとの互換性が損なわれる可能性があるため、名前の衝突に注意する必要がある。
(3)将来の変更への依存: JavaScript や関連の仕様が変更された場合、その変更がコードに影響を与える可能性がある。