ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript Advanced Programming Extension -- Dynamic Prototype_JavaScript スキルについて

JavaScript Advanced Programming Extension -- Dynamic Prototype_JavaScript スキルについて

WBOY
WBOYオリジナル
2016-05-16 18:16:44965ブラウズ

ただし、著者の Nicholas C. Zakas は、[ダイナミック プロトタイプ] メソッドを使用してオブジェクトを作成するときに起こり得る問題と解決策については詳しく説明しませんでした。ただし、[動的プロトタイプ] のボトルネックのみが継承時に説明されます。つまり、サブクラスの継承が実行される場合、動的プロトタイプでは実現できません。
原文はおおよそ次のとおりです。
継承メカニズムを動的にできない理由は、プロトタイプ オブジェクトの一意性です。コード例:

コードをコピー コードは次のとおりです。

function A (i) {
this.a = i;
if (typeof A._init == '未定義') {
A.prototype.func = function () {
return
}
A._init = 1;
}
}
関数 subA (j) {
this.j = j; subA のタイプ == '未定義') {
subA.prototype = new A();
subA.prototype.func_sub = function () {
return j; ._init = 1;
}
}
var sub_a = new subA(1);
alert(sub_a.func_sub()); //エラー: sub_a.func_sub は関数ではありません>

Nicholas 氏は、コードが実行される前に、オブジェクトはインスタンス化され、プロトタイプと接続されているため、現時点でプロトタイプ オブジェクトを置き換えても影響はないと説明しました。アクセスできないため、将来のオブジェクトのみがこの変更を反映します。その場合、最初のインスタンス オブジェクトは正しくなくなります。ただし、2 番目以降のサブクラス インスタンスは問題ありません。
解決策は、コンストラクターの外側に新しいプロトタイプ オブジェクトを割り当てることです:



コードをコピーします
コードは次のとおりです: function A (i) { this.a = i; if (typeof A._init == '未定義') {
A.prototype.func = function ( ) {
return 0;
}
A._init = 1;
}
}
関数 subA (j) {
A.call(this, 1);
this .j = j;
if (typeof subA._init == '未定義') {
subA.prototype.func_sub = function () {
return j; >subA._init = 1;
}
}
subA.prototype = new A();
var sub_a = new subA(1); ; //2


残念ながら、これは動的プロトタイプを使用する目的に反します。
動的プロトタイプを使用する本来の目的は、コンストラクターが「国を統一」できるようにし、プロトタイプ メソッドがクラス構築の一部であると視覚的に人々に感じさせることです。
上記は、『上級 JavaScript プログラミング』の動的プロトタイプ継承セクションの一般的な内容です。

しかし、ニコラスは前の章でオブジェクトの構築について話しました。動的プロトタイプ] アプローチでは、同じ問題が忘れられていたようです。上記の最後の例を見てみましょう:



コードをコピーします


コードは次のとおりです:
var Obj = 関数 (名前) { this.name = 名前; this.flag = new Array('A', 'B'); if (typeof Obj._init == '未定義' ) { Obj.prototype = { showName : function () {
alert(this.name);
}
}; }
}
var obj1 = new Obj('aa');
var obj2 = new Obj('bb'); //エラー: 関数ではありません。
obj2.showName(); // bb;


はい、この問題は実際にはサブクラスの継承で発生する問題と同じです。オブジェクト。将来のインスタンスでのみ表示されます。 Nicholas が動的プロトタイプ継承を処理する方法に従う場合、プロトタイプ オブジェクトはコンストラクターの外部でのみ再割り当てできることを意味します。つまり、これは[コンストラクターとプロトタイプのハイブリッド]メソッドになるのではありませんか?いわゆる [動的プロトタイプ] メソッドはもう存在しません...

実際、基本的に副作用のないオブジェクトを構築するメソッドである [コンストラクターとプロトタイプのハイブリッド] がなぜ採用されているのかを考えることができます。 by [ダイナミックプロトタイピング]メソッドに関するセクションを作成します。作者の意図は、コンストラクターをより視覚的に統一することだけでしょうか?実際、視覚的な統一性が必要な限り、動的なプロトタイプは必要ありません。




コードをコピー

コードは次のとおりです。


var Obj = function () {
function __initialize (name) {
this.name = name; this.flag = new Array('A', 'B'); __initialize.prototype = { showName : function () { alert(this.name); }, showFlag : function () {
alert(this.flag);
>return __initialize ;
}();
var obj('aa');
var obj('bb'); // aa
obj2.showName() // bb


実際、上記のメソッドは、Obj のコンストラクター内の __initialize を通じてプロパティが初期化され、__initialize.prototype プロトタイプ初期化メソッドが使用されます。ちょっとした「ズル」のように感じます。 __initialize は Obj の初期化を表します。
以下は、tangoboy の「構築されたクラス」のカプセル化です。実際、考え方は基本的に上記と同じです。唯一の違いは、属性も追加していることです。プロトタイプ モードで作成され、初期化プロパティとメソッドがコンストラクター パラメーター オブジェクトにスローされました。簡単にカスタマイズできます:
コードをコピー コードは次のとおりです:

/* == フォームTangoboy == */
window['$Class'] = {
//混合コンストラクター/プロトタイプメソッドを使用してクラスを作成します
create: function(config) {
var obj = function() {}, config = config||{};
//フィルターコンストラクターとプロトタイプメソッド
obj = obj.prototype.constructor = config["__"]||obj;
delete config["__ "] ;
obj.prototype = config;
return obj;
}
}
/* -- 例 -- */
var man = $Class.create({
__ : function (name) {
this.name = name;
},
性別 : '男性',
showName : function () {
alert(this.name) );
}
});
var me = new man('ru')
me.showName(); //ru

視覚的な統一を追求したい場合は、動的プロトタイピングを行わずに実現することもできます。結局のところ、上記の考え方を見ると、最も一般的に使用されている「クラス構築」メソッドに遡ることができます:
コードをコピーコードは次のとおりです。

var Class = {
create : function () {
return function () {
this.initialize.apply(this, argument);
}
}
}

上記のコードは誰でもよく知っていると思いますが、注意深く調べてみると、実際には上記と一致していることがわかります。このコードでは、initialize 関数が初期化エージェントとして使用され、視覚的な統一が完了します。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。