ホームページ > 記事 > ウェブフロントエンド > JavaScriptプロトタイプの詳しい説明
以下は、2008年にGithubが作成されて以来、さまざまなプログラミング言語のランキングです
その中で、JavaScriptは2015年から第1位を占め、最も使用されている言語となっています初期の頃、JS の使用は主にブラウザーに集中していましたが、node.js がサーバー開発に参入し、React Native が徐々にモバイル端末に浸透するにつれて、JS のフルスタック時代が到来します。そして、JS の世界には「JS で開発できるアプリケーションはすべて、最終的には JS で開発されるようになる」という有名な格言があります。怖いですか?と聞いただけです。
そうは言っても、私は JS が世界で最高の言語だと言いたいわけではありません (もちろん PHP ですよね? ←_←)。また、JS が誰かに取って代わるとも思っていません。その JavaScript は、(Web 側だけでなく) 誰もが理解し、学習する必要がある言語ツールになります。
オブジェクト指向は、現実世界の抽象化であり、現在、オブジェクトの実装に使用されています。クラスは、クラスのカプセル化と継承を通じて現実世界をマップします。 Java、C#、さらには Python も含めて、それらはすべてクラス設計を通じてオブジェクト指向設計を実装します。しかし、よく考えてみると、現実世界にはクラスという概念はなく、オブジェクトが異なるだけなので、クラスではなくオブジェクトとオブジェクトの間に継承関係が発生することに問題があると感じるでしょう。たとえば、子はオブジェクトであり、親もオブジェクトです。JS もオブジェクト指向プログラミング言語ですが、そのオブジェクト指向へのアプローチはクラスではなくプロトタイプに基づいています。この考え方は、オブジェクト リンク他のオブジェクトとも呼ばれます。つまり、現実世界の関係 (継承など) がオブジェクトに直接マッピングされます。
2.2 プロトタイプの概念
それでは、まずプロトタイプのコンセプトについて話しましょう。 JS のすべてはオブジェクトであり、各オブジェクトにはプロトタイプがあります (Object を除く)。このプロトタイプは Java の親クラスに似ているため、基本的にはプロトタイプをこのオブジェクト、つまりすべてのオブジェクトの親オブジェクトと考えることができます。 (オブジェクトを除く) は内部に独自の親オブジェクトを格納しており、この親オブジェクトがプロトタイプです。一般に作成されるオブジェクトがプロトタイプを指定しない場合、そのプロトタイプは Object になります (これは、デフォルトで Object クラスから継承する Java のすべてのクラスと非常に似ています)。
2.3 オブジェクトの作成
//第一种,手动创建 var a={'name':'lala'}; //第二种,构造函数 function A(){ this.name='lala'; } var a=new A(); //第三种,class (ES6标准写法) class A{ constructor(){ super(); this.name='lala'; } } var a=new A() //其实后面两种方法本质上是一种写法
これら 3 つの記述方法で作成されるオブジェクトのプロトタイプ (親オブジェクト) はすべて Object です。特筆すべき点は、class や extends などのキーワードを導入することで、ES6 はコンストラクターを糖衣構文の形式でクラスの概念にラップし、誰でも理解しやすくしていることです。開発者がプロトタイプやプロトタイプ チェーンに注意を払うことにエネルギーを費やさなくなることが期待されています。また、プロトタイプの設計意図がクラスの設計意図と同じであることも十分に実証されています。
2.4 オブジェクトのプロトタイプを表示する
function A(){ this.name='lala'; } var a=new A(); console.log(a.__proto__) //输出:Object {} //推荐使用这种方式获取对象的原型 console.log(Object.getPrototypeOf(a)) //输出:Object {}
オブジェクトの作成方法に関係なく、デフォルトのプロトタイプは Object であることに注意してください。ここで特に注意すべき点は、オブジェクトがコンストラクターを通じて作成されることです。 A 自体もオブジェクトであり、A にはプロトタイプを表す 2 つの点があり、それぞれ proto とprototype であり、2 つの属性は同じではありません
function A(){ this.name='lala'; } var a=new A(); console.log(A.prototype) //输出:Object {} console.log(A.__proto__) //输出:function () {} console.log(Object.getPrototypeOf(A)) //输出:function () {}
関数のプロトタイプ属性は、独自のプロトタイプ属性値を関数に割り当てるだけです。コンストラクターとして作成されたオブジェクトのプロトタイプ。実際には、関数自体として、そのプロトタイプは関数オブジェクトである必要があり、関数オブジェクトのプロトタイプは Object になります。
要するに、プロトタイプの表示とプロトタイプの設定には、ES6 推奨の方法を使用することをお勧めします。
2.5 プロトタイプの使用法
function A(){ this.name='world '; } function B(){ this.bb="hello" } var a=new A(); var b=new B(); Object.setPrototypeOf(a,b); //将b设置为a的原型,此处有一个问题,即a的constructor也指向了B构造函数,可能需要纠正 a.constructor=A; console.log(a.bb) //输出 hello(補足)
ES6でやるともっと簡単で、prototype属性も必要ありません
class B{ constructor(){ this.bb='hello' } } class A extends B{ constructor(){ super() this.name='world' } } var a=new A(); console.log(a.bb+" "+a.name); //输出hello world console.log(typeof(A)) //输出 "function"
どうでしょうか?プロトタイプの痕跡はまったくありませんか?これはクラスの継承と似ていますが、クラス A の型が実際には関数であることもわかります。つまり、クラスは JS の構文糖衣の一種であり、JS 継承の本質はまだプロトタイプです。ただし、ES6 では導入されています。 class と extends プロトタイプの概念を隠すことは、クラス継承に基づいたオブジェクト指向プログラミング言語を長年研究してきたプログラマーにとって非常に友好的な動きでもあります。
私の提案は、プロトタイプをできるだけ理解し、クラスのような構文シュガーをできるだけ使用することです。
この概念は実際には比較的単純になっており、クラスの継承チェーンと比較することができます。つまり、各オブジェクトのプロトタイプがオブジェクトに到達するまで上向きに追跡され、オブジェクトを接続するチェーンが形成されます。現在のオブジェクトのプロパティを検索するときに、オブジェクトが見つからない場合は、このチェーンに沿って検索されます。まだ見つからない場合は、未定義と報告されます。これは、プロトタイプ チェーンが長すぎてはいけないことを意味します。長すぎると、効率の問題が発生します。
プロトタイプの概念の理解
類似クラスの継承、オブジェクトのプロトタイプはオブジェクトの親オブジェクトとして理解できます