ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptプロトタイプの詳しい説明

JavaScriptプロトタイプの詳しい説明

黄舟
黄舟オリジナル
2017-02-22 13:22:571013ブラウズ


1、はじめに

以下は、2008年にGithubが作成されて以来、さまざまなプログラミング言語のランキングです

JavaScriptプロトタイプの詳しい説明

その中で、JavaScriptは2015年から第1位を占め、最も使用されている言語となっています初期の頃、JS の使用は主にブラウザーに集中していましたが、node.js がサーバー開発に参入し、React Native が徐々にモバイル端末に浸透するにつれて、JS のフルスタック時代が到来します。そして、JS の世界には「JS で開発できるアプリケーションはすべて、最終的には JS で開発されるようになる」という有名な格言があります。怖いですか?と聞いただけです。

そうは言っても、私は JS が世界で最高の言語だと言いたいわけではありません (もちろん PHP ですよね? ←_←)。また、JS が誰かに取って代わるとも思っていません。その JavaScript は、(Web 側だけでなく) 誰もが理解し、学習する必要がある言語ツールになります。

2. オブジェクト指向 (OOP)

2.1 実装のアイデア

オブジェクト指向は、現実世界の抽象化であり、現在、オブジェクトの実装に使用されています。クラスは、クラスのカプセル化と継承を通じて現実世界をマップします。 Java、C#、さらには Python も含めて、それらはすべてクラス設計を通じてオブジェクト指向設計を実装します。しかし、よく考えてみると、現実世界にはクラスという概念はなく、オブジェクトが異なるだけなので、クラスではなくオブジェクトとオブジェクトの間に継承関係が発生することに問題があると感じるでしょう。たとえば、子はオブジェクトであり、親もオブジェクトです。JS もオブジェクト指向プログラミング言語ですが、そのオブジェクト指向へのアプローチはクラスではなくプロトタイプに基づいています。この考え方は、オブジェクト リンク他のオブジェクトとも呼ばれます。つまり、現実世界の関係 (継承など) がオブジェクトに直接マッピングされます。

2.2 プロトタイプの概念

実際、私はプロトタイプの概念そのものに加えて、それに関連するオブジェクトの生成、コンストラクター、プロトタイプとプロトタイプの違い、およびオブジェクトにプロトタイプがない理由など、関連する概念を数日間勉強しました。プロトタイプを指すプロトタイプ属性ではなく、プロトタイプを指すために proto を使用しますか?

それでは、まずプロトタイプのコンセプトについて話しましょう。 JS のすべてはオブジェクトであり、各オブジェクトにはプロトタイプがあります (Object を除く)。このプロトタイプは Java の親クラスに似ているため、基本的にはプロトタイプをこのオブジェクト、つまりすべてのオブジェクトの親オブジェクトと考えることができます。 (オブジェクトを除く) は内部に独自の親オブジェクトを格納しており、この親オブジェクトがプロトタイプです。一般に作成されるオブジェクトがプロトタイプを指定しない場合、そのプロトタイプは Object になります (これは、デフォルトで Object クラスから継承する Java のすべてのクラスと非常に似ています)。

2.3 オブジェクトの作成

JS ではオブジェクトを作成する方法がたくさんありますが、最も一般的な方法は次のとおりです:

//第一种,手动创建
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 オブジェクトのプロトタイプを表示する

オブジェクトが作成された後、そのプロトタイプを表示するには複数の方法がありましたが、ES6 のリリース後は、オブジェクトの proto 属性を使用することが推奨されています。 Object.getPrototypeOf() メソッドを使用してオブジェクトのプロトタイプを取得します

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 プロトタイプの概念を隠すことは、クラス継承に基づいたオブジェクト指向プログラミング言語を長年研究してきたプログラマーにとって非常に友好的な動きでもあります。

私の提案は、プロトタイプをできるだけ理解し、クラスのような構文シュガーをできるだけ使用することです。


2.6 プロトタイプチェーン

この概念は実際には比較的単純になっており、クラスの継承チェーンと比較することができます。つまり、各オブジェクトのプロトタイプがオブジェクトに到達するまで上向きに追跡され、オブジェクトを接続するチェーンが形成されます。現在のオブジェクトのプロパティを検索するときに、オブジェクトが見つからない場合は、このチェーンに沿って検索されます。まだ見つからない場合は、未定義と報告されます。これは、プロトタイプ チェーンが長すぎてはいけないことを意味します。長すぎると、効率の問題が発生します。

3. まとめ

  • プロトタイプの概念の理解

    • 類似クラスの継承、オブジェクトのプロトタイプはオブジェクトの親オブジェクトとして理解できます

  • プロトタイプの使用

    • 可能な限りES6標準を使用し、class、extends、Object.getPrototype()、Object.setPrototype()などを使用してください。

  • 注意点

    • プロトタイプ継承チェーンは長すぎます

    • プロトタイプを指定する場合、コンストラクターも変更されることに注意してください。

4、追記(補足)

私の分析が非常に抽象的だと思われる方もいると思いますので、JSにおけるプロトタイプ、つまりプロトタイプとは何かを一言で理解したい方のためにもう一度まとめておきます。オブジェクトの は、オブジェクトの親オブジェクトを参照します。すべてのオブジェクトには親オブジェクトがあり、親オブジェクト自体にも親オブジェクト (祖父オブジェクト?) があります。プロトタイプチェーンに関しては、これは過去の家系図の概念に非常に似ており、父親、祖父、曾祖父を最後まで追跡することができます。がオブジェクトと比較されると、このチェーンがプロトタイプ チェーンになります。

上記は JavaScript プロトタイプの詳細な説明です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) をご覧ください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。