以下のコードは、JavaScript で継承を実行するために私が見た中で最高のものの 1 つです。
Object.create(proto [, propertiesObject ]) については、MDN hereで説明されています。
以下では、Jon は ExtendBase と呼ばれるベースの空のオブジェクトを定義し、extend と呼ばれる列挙不可能な関数プロパティを追加します。これは引数として単一の新しいオブジェクトを取ります。
そのオブジェクトには、ベース オブジェクトに追加されるメソッドやデータなどの列挙可能なプロパティが含まれている必要があります。
渡されたオブジェクトからすべての列挙可能なプロパティを取得し、必要な記述子の配列を作成して、それらのプロパティの名前を使用して Object.create に渡します。次に、親オブジェクトをプロトタイプとして使用し、結果の記述子を新しいプロパティとして使用して、Object.create() 呼び出しで子オブジェクトに直接追加します。
ご覧のとおり、メソッドを含むプロパティでオブジェクト引数を使用して、渡されたオブジェクトのプロパティを失うことなく親を拡張し、その結果、親をプロトタイプとして持つ子オブジェクトになり、渡されたオブジェクトの列挙可能なオブジェクトが直接追加されます。子供に。
ただし、これは、意味のある方法で親を新しい子に拡張するために正気で作成された他のオブジェクトを使用して親オブジェクトを拡張することを意図しながら、クリーンなプロトタイプ チェーンを維持します。
ライブ サンプルはこちら(Chrome で F12 を押してコンソール出力を表示するか、FireFox で FireBug を使用するなど)
JavaScript:
// Original Author: FireFly - Jonas Höglund - ##javascript channel
// on irc.freenode.net - see THANKS File. Updated to private data
// members and passable initial parameters by Scott Sanbar
///////////////
// Library code
///////////////
var ExtendBase = {};
Object.defineProperty(ExtendBase, 'extend', {
enumerable:false, value:function (obj) {
'use strict';
var descs = {};
Object.getOwnPropertyNames(obj).forEach(function (key) {
descs[key] = Object.getOwnPropertyDescriptor(obj, key)
});
return Object.create(this, descs);
}
});
///////////////
// Sample Usage
///////////////
function PersonObj(nam) {
return {
name:new function () {
var name = nam;
this.set = function (value) {
name = value;
};
this.get = function () {
return name;
}
},
// A person can tell you its name.
talk:function () {
return "Hello, I'm " + this.name.get();
}
}
}
;
function WorkingPersonObj(occ) {
return {
occupation:new function () {
var occupation = occ;
this.set = function (value) {
occupation = value;
};
this.get = function () {
return occupation;
}
},
// A working person also tells you their occupation when they talk.
talk:function () {
return Person.talk.call(this) + " and I am a " + this.occupation.get();
}
}
}
;
var hush = {
hush:function () {
return "I am supposed to be quiet";
}
};
var Person = ExtendBase.extend(new PersonObj('Harry'));
var WorkingPerson = Person.extend(new WorkingPersonObj('wizard'));
var wp1 = WorkingPerson.extend(hush);
console.log(wp1.talk()); // "Hello, I'm Harry and I am a wizard"
console.log(wp1.hush()); // "I am supposed to be quiet"
wp1.name.set("Elijah");
wp1.occupation.set("prophet");
console.log(wp1.talk()); // "Hello, I'm Elijah and I am a prophet"
console.log(wp1.name.get());
console.log(wp1.occupation.get());