わかりましたので、プロトタイプの継承を希望どおりに機能させようとしています。いくつかの例を読みましたが、必要な要件の 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を避けていることに注意してください。