Javascriptプログラミングにおけるいくつかの継承方式の比較分析
5133 ワード
Javascriptプログラミングにおけるいくつかの継承方式の比較を例として解析した.皆さんの参考にしてください.具体的には以下の通りです.
冒頭
「厳格」の意味ではjavascriptは本当のオブジェクト向け言語ではありません.この説の原因は一般的にjavascriptが弱いタイプの言語としてjavaやc#のような強い言語の継承方式と大きく異なると考えられているため、デフォルトでは非主流のオブジェクト向け方式であり、「非完全なオブジェクト向け」言語として記述されている本も多い.実は個人は、どんな方式が重要ではないと思って、重要なのは対象に向かう思想を持っているかどうかで、javascriptは対象言語に向いていないと言って、往々にしてjavascriptの継承方式を深く研究したことがないかもしれないので、この文を書いて交流に供します.
Javascriptによる継承が必要な理由
初期のpcマシンの性能は確かにお世辞を言う勇気がなくて、すべての圧力はすべてサーバーの端で、クライアントのブラウザは純粋に飾りです.加えて、当時流行していたtableレイアウトと電話線のインターネット接続方式は、1つのページを閲覧するのに十分なカードをもたらした.今のインターネット时代は急速に発展して、パソコンのハードウェアはきわめて大きく向上して、クライアントのブラウザの性能も非常に酸っぱくてさわやかで、web开発のモードもそっと変えています:サービス端は以前のように“苦労します”ではありませんて、代わりにできるだけブラウザにもっと多くの任务を引き受けさせて、このようにして、圧力はすべてのクライアントの上で割り当てます企業はコストを節約するだけでなく、Webフロントエンドの開発をより面白くします.ますます多くのフロントエンドフレームワークが次々と現れ、多くのフロントエンドのMVCフレームワークも現れています.このような背景の下で、javascriptの役割は決して簡単な検証だけではなく、いくつかのリクエストを送信したりDOMを操作したりする必要があります.より多くの場合、フロントエンドのルーティングやビジネス層のような役割を果たす必要があります.javascriptは、フロントデータの抽出(model)を含む多くの論理的なタスクを行う必要があります.オブジェクト向けの思考を駆使してこそ、抽出データをうまく処理できるので、継承はここで重要です.
シンプルなニーズから
フロントからPersonというモデルを抽出します.基本属性nameとageがあり、デフォルトでは誰もが話すので、話の機能sayをプロトタイプオブジェクトに置いて、インスタンスごとに楽しむことができます.現在、ManではPersonの基本プロパティを継承し、それに独自のプロパティを追加する必要があります.
いくつかの主流の継承方法を紹介します.
1.プロトタイプチェーン継承
この継承方式は直接的で,Personのすべての属性メソッド(インスタンス上とプロトタイプ上の)を取得するために,親クラスのインスタンスnew Person('pursue')を子クラスのプロトタイプに直接付与したが,実際には子クラスのインスタンスman 1,man 2自体は完全に空のオブジェクトであり,すべての属性とメソッドはプロトタイプチェーンに行かなければならないので,見つかった属性メソッドは同じである.したがって,プロトタイプチェーン継承を直接利用することは現実的ではない.
2.コンストラクション関数による継承
ここで、サブクラスはコンストラクション関数でapplyを利用して親のコンストラクション関数を呼び出し、親の属性を継承する効果を達成します.プロトタイプチェーンを直接利用するよりもずっとよく、少なくとも各インスタンスには自分のリソースがありますが、この方法は親のインスタンス属性を継承するしかありません.そのためsay方法は見つかりません.親のすべての属性と方法を継承するために、プロトタイプチェーンを修正し、組合せ継承方式を導入します.
3.組合せ継承
man 1とman 2のインスタンス属性は、実際にはプロトタイプ属性を上書きしていますが、プロトタイプ上のsayメソッドを上書きする必要はありません(それらはありませんので)、ここでman 1.say==man 2.sayはtrueを返します.したがって、上書きされていないプロトタイプ属性は、すべてのインスタンスで共有されているため、十分注意する必要があります.
4.寄生組合せ継承
正直に言うと、次のような形でこの名前を呼ぶのは分かりませんが、それは確かに最も流行しており、最も古典的なjavascriptの継承方法です.実際には、プロトタイプオブジェクトの構造を理解するだけでいいです.
寄生組合せ継承と上記組合せ継承の違いは、サブクラスプロトタイプオブジェクトを構築する方法(a.およびb.)のみであり、ここでは、入力されたobjオブジェクトを浅いコピーするObject.creat(obj)方法が用いられている.
したがって,a.は,子クラスの原型オブジェクトと親クラスの原型オブジェクトとをうまく接続し,一般的な組合せ継承のように直接子クラスの原型を複製する(Man.prototype=new Person();)のではなく,暴力的に属性を覆っているだけである.寄生組合せ継承方式では,インスタンス属性とプロトタイプ属性をそれぞれ継承し,実現上より合理的である.
注意:コードb.はinstanceofの結果を変えることはありませんが、construcorを使用する必要があるシーンでは、より厳格になります.
JavaScriptプログラムの設計に役立つことを願っています.
冒頭
「厳格」の意味ではjavascriptは本当のオブジェクト向け言語ではありません.この説の原因は一般的にjavascriptが弱いタイプの言語としてjavaやc#のような強い言語の継承方式と大きく異なると考えられているため、デフォルトでは非主流のオブジェクト向け方式であり、「非完全なオブジェクト向け」言語として記述されている本も多い.実は個人は、どんな方式が重要ではないと思って、重要なのは対象に向かう思想を持っているかどうかで、javascriptは対象言語に向いていないと言って、往々にしてjavascriptの継承方式を深く研究したことがないかもしれないので、この文を書いて交流に供します.
Javascriptによる継承が必要な理由
初期のpcマシンの性能は確かにお世辞を言う勇気がなくて、すべての圧力はすべてサーバーの端で、クライアントのブラウザは純粋に飾りです.加えて、当時流行していたtableレイアウトと電話線のインターネット接続方式は、1つのページを閲覧するのに十分なカードをもたらした.今のインターネット时代は急速に発展して、パソコンのハードウェアはきわめて大きく向上して、クライアントのブラウザの性能も非常に酸っぱくてさわやかで、web开発のモードもそっと変えています:サービス端は以前のように“苦労します”ではありませんて、代わりにできるだけブラウザにもっと多くの任务を引き受けさせて、このようにして、圧力はすべてのクライアントの上で割り当てます企業はコストを節約するだけでなく、Webフロントエンドの開発をより面白くします.ますます多くのフロントエンドフレームワークが次々と現れ、多くのフロントエンドのMVCフレームワークも現れています.このような背景の下で、javascriptの役割は決して簡単な検証だけではなく、いくつかのリクエストを送信したりDOMを操作したりする必要があります.より多くの場合、フロントエンドのルーティングやビジネス層のような役割を果たす必要があります.javascriptは、フロントデータの抽出(model)を含む多くの論理的なタスクを行う必要があります.オブジェクト向けの思考を駆使してこそ、抽出データをうまく処理できるので、継承はここで重要です.
シンプルなニーズから
フロントからPersonというモデルを抽出します.基本属性nameとageがあり、デフォルトでは誰もが話すので、話の機能sayをプロトタイプオブジェクトに置いて、インスタンスごとに楽しむことができます.現在、ManではPersonの基本プロパティを継承し、それに独自のプロパティを追加する必要があります.
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log('hello, my name is ' + this.name);
};
function Man() {
//my own properties
}
いくつかの主流の継承方法を紹介します.
1.プロトタイプチェーン継承
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log('hello, my name is ' + this.name);
};
function Man() {
}
Man.prototype = new Person('pursue');
var man1 = new Man();
man1.say(); //hello, my name is pursue
var man2 = new Man();
console.log(man1.say === man2.say);//true
console.log(man1.name === man2.name);//true
この継承方式は直接的で,Personのすべての属性メソッド(インスタンス上とプロトタイプ上の)を取得するために,親クラスのインスタンスnew Person('pursue')を子クラスのプロトタイプに直接付与したが,実際には子クラスのインスタンスman 1,man 2自体は完全に空のオブジェクトであり,すべての属性とメソッドはプロトタイプチェーンに行かなければならないので,見つかった属性メソッドは同じである.したがって,プロトタイプチェーン継承を直接利用することは現実的ではない.
2.コンストラクション関数による継承
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
Person.apply(this, arguments);
}
//Man.prototype = new Person('pursue');
var man1 = new Man('joe');
var man2 = new Man('david');
console.log(man1.name === man2.name);//false
man1.say(); //say is not a function
ここで、サブクラスはコンストラクション関数でapplyを利用して親のコンストラクション関数を呼び出し、親の属性を継承する効果を達成します.プロトタイプチェーンを直接利用するよりもずっとよく、少なくとも各インスタンスには自分のリソースがありますが、この方法は親のインスタンス属性を継承するしかありません.そのためsay方法は見つかりません.親のすべての属性と方法を継承するために、プロトタイプチェーンを修正し、組合せ継承方式を導入します.
3.組合せ継承
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
Person.apply(this, arguments);
}
Man.prototype = new Person();
var man1 = new Man('joe');
var man2 = new Man('david');
console.log(man1.name === man2.name);//false
console.log(man1.say === man2.say);//true
man1.say(); //hello, my name is joe
man 1とman 2のインスタンス属性は、実際にはプロトタイプ属性を上書きしていますが、プロトタイプ上のsayメソッドを上書きする必要はありません(それらはありませんので)、ここでman 1.say==man 2.sayはtrueを返します.したがって、上書きされていないプロトタイプ属性は、すべてのインスタンスで共有されているため、十分注意する必要があります.
4.寄生組合せ継承
正直に言うと、次のような形でこの名前を呼ぶのは分かりませんが、それは確かに最も流行しており、最も古典的なjavascriptの継承方法です.実際には、プロトタイプオブジェクトの構造を理解するだけでいいです.
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log('hello, my name is ' + this.name);
};
function Man(name, age) {
Person.apply(this, arguments);
}
Man.prototype = Object.create(Person.prototype);//a.
Man.prototype.constructor = Man;//b.
var man1 = new Man('pursue');
var man2 = new Man('joe');
console.log(man1.say == man2.say);
console.log(man1.name == man2.name);
寄生組合せ継承と上記組合せ継承の違いは、サブクラスプロトタイプオブジェクトを構築する方法(a.およびb.)のみであり、ここでは、入力されたobjオブジェクトを浅いコピーするObject.creat(obj)方法が用いられている.
function create(obj){
function T(){};
T.prototype = obj;
return new T();
}
したがって,a.は,子クラスの原型オブジェクトと親クラスの原型オブジェクトとをうまく接続し,一般的な組合せ継承のように直接子クラスの原型を複製する(Man.prototype=new Person();)のではなく,暴力的に属性を覆っているだけである.寄生組合せ継承方式では,インスタンス属性とプロトタイプ属性をそれぞれ継承し,実現上より合理的である.
注意:コードb.はinstanceofの結果を変えることはありませんが、construcorを使用する必要があるシーンでは、より厳格になります.
JavaScriptプログラムの設計に役立つことを願っています.