わかりましたので、プロトタイプの継承を希望どおりに機能させようとしています。いくつかの例を読みましたが、必要な要件の 1 つは、親クラスのメソッドを簡単に呼び出せることでした。そして、モジュール パターン+ jQuery ボイラープレート スタイルに従いたいと思います。ここでは、デフォルト、空でないコンストラクター関数、およびプロトタイプ関数があります。
;(function($, window, undefined){
"use_strict";
var defaultsHuman = {
id: 1,
age: 0
};
function Human( options ){
this.options = $.extend(defaultsHuman, options || {});
this.age = this.options.age;
this.gender = 'male';
//save originals for ref
this._defaults = defaultsHuman;
};
Human.prototype = {
_className: 'Human',
init: function(){
console.log('My class is ' + this._className + ' my gender is ' + this.gender + ' and my age is ' + this.age);
}
};
//Right now Human's function prototype's constructor is Object(), but IE8 uses constructor.prototype
//well now it's Object which is native so it's undefined?, anyways we lose the original reference to the constructor from the instance
//so lets reset it to the constructor - constructor is now enumerable!
Human.prototype.constructor = Human; //note this is cyclical!
//END fn Human
var defaultsChild = {
name: ''
};
//we want to create a new constructor B that has properties, its constructor prototype is an instance of Human
function Child( options ){
//merge the parent defaults with my defaults, then extend dynamic options on top
this.options = $.extend(this.constructor.prototype._defaults, defaultsChild, options || {});
this.name = options.name;
//A.call(this);
};
//new Human() calls Human's constructor and returns an object with prototype set to Human.prototype
Child.prototype = new Human();
$.extend(Child.prototype, {
school: 'St. Peter\'s',
init: function(){
//create reference to super class
this._super = this.constructor.prototype;
//this._super.init.call(this);
this._super.init();
console.log('My name is ' + this.name + ' and my school is ' + this.school);
}
});
Child.prototype.constructor = Human;
//END Child
//export modules - old method before define
window.Human = Human;
window.Child = Child;
})(jQuery, window, undefined);
//some other closure somewhere where it is required in
;(function(window, undefined, Human, Child){
"use_strict";
var me = new Child({
name: 'Clarence',
age: 7
}).init();
})(window, undefined, Human, Child);
私を混乱させているのは、Human's init関数では がインスタンスthisを参照しているHumanが、状態では がHuman constructor実行されていないため、静的に男性に設定されている性別さえ存在しないことです。
My class is Human my gender is undefined and my age is undefined
My name is Clarence and my school is St. Peter's
代わりに呼び出すことでこれを簡単に修正できthis._super.init.call(this);ます。おそらくこれを行うだけですが、まだ興味があります。
コンストラクターが実行された後、Child の関数プロトタイプを完全な Human オブジェクト に明示的に設定しますChild.prototype = new Human();。child の最終インスタンスを調べるとme、コンストラクターが実行された場所で (予想どおり) プロトタイプは HumanですがHuman init、this変数内では、人間のコンストラクターは実行したことがありません。
スーパーを参照this._super = this.constructor.prototype;すると、これはここで宣言されたプロトタイプへの参照ではありませんChild.prototype = new Human();か? そして、私が呼び出すthis.super.init()と、返されたもののコンテキストで実行されていませんnew Human()か?
また、IE8 との互換性のためにprotoを避けていることに注意してください。