JS コア シリーズ: プロトタイプ オブジェクトとプロトタイプ チェーンの簡単な説明

大家讲道理
リリース: 2017-01-24 11:45:36
オリジナル
1073 人が閲覧しました

JavaScriptではすべてがオブジェクトですが、オブジェクトにも種類があり、通常のオブジェクト(Object)と関数オブジェクト(Function)の2つに大別されます。

一般に、new Function によって生成されたオブジェクトは Function オブジェクトであり、それ以外のオブジェクトは通常のオブジェクトです。

例:

function f1(){
    //todo
}
var f2 = function(){
    //todo
};
var f3 = new Function('x','console.log(x)');

var o1 = {};
var o2 = new Object();
var o3 = new f1();

console.log(
    typeof f1,//function
    typeof f2,//function
    typeof f3,//function
    typeof o1,//object
    typeof o2,//object
    typeof o3 //object
);
>> function function function object object object
ログイン後にコピー

f1 は関数宣言であり、f2 は実際には関数式である f2 に代入されますが、これは一般的ではありません。関数式とも呼ばれます。

Function は JS に付属するオブジェクトです。f1 と f2 が作成されると、JS は new Function() を通じてこれらのオブジェクトを自動的に構築します。したがって、これら 3 つのオブジェクトはすべて new Function() によって作成されます。

Javascript でオブジェクトを作成するには、オブジェクト リテラルと新しい式を使用する 2 つの方法があります。o1 と o2 の作成は、これら 2 つの方法に対応します。Java と C# を使用して理解する場合、o3 はインスタンスです。 f1、o3、および f1 のオブジェクトは同じ型です。少なくとも私はそう思っていましたが、そうではありません...

それでは、非常に簡単です。o3 が生成されるかどうかを確認してください。 new Function は、Function オブジェクトではないため、明らかにそうではありません。通常のオブジェクトです。

関数オブジェクトと通常のオブジェクトを簡単に理解した後、JavaScript のプロトタイプとプロトタイプ チェーンを見てみましょう:

JS では、関数オブジェクト f1 が作成されるたびに、いくつかのプロパティがオブジェクトに組み込まれます。プロトタイプと __proto__ を含むプロトタイプは、f1 のいくつかの属性とメソッドを記録するプロトタイプ オブジェクトです。

プロトタイプは f1 には見えないことに注意してください。つまり、f1 はプロトタイプ内のプロパティとメソッドを検索しません。

function f(){}
f.prototype.foo = "abc";
console.log(f.foo); //undefined
ログイン後にコピー

それでは、プロトタイプは何に役立つのでしょうか? 実際、プロトタイプの主な機能は継承です。 平たく言えば、プロトタイプで定義されたプロパティとメソッドは、それ自体の「子孫」用に予約されているため、サブクラスはプロトタイプのプロパティとメソッドに完全にアクセスできます。

f1 がプロトタイプを「子孫」に残す方法を知りたい場合は、JS のプロトタイプ チェーンを理解する必要があります。このとき、JS の __proto__ は非常に奇妙に見え、非常に隠されています。あまり見かけませんが、この関数は通常のオブジェクトと関数オブジェクトの両方に存在し、JS が新しい式を通じてオブジェクトを作成するときに、通常は親クラスを保存します。プロトタイプは新しいオブジェクトの __proto__ 属性に割り当てられ、世代から世代への継承を形成します...

function f(){}
f.prototype.foo = "abc";var obj = new f();
console.log(obj.foo); //abc
ログイン後にコピー

これで、obj の __proto__ が f のプロトタイプを保存し、次に f のプロトタイプに保存されることがわかりました。 __proto__ に保存されていますか? 以下の図を見てください:

図に示すように、f.prototype の __proto__ に保存されているのは Object.prototype であり、Object.prototype オブジェクトにも __proto__ があり、そこから出力されます。 , Object.prototype.__proto__ は null で、obj オブジェクト プロトタイプ チェーンの終わりを示します。以下の図に示すように:

obj オブジェクトがこのようなプロトタイプチェーンを持った後、obj.foo が実行されると、obj は最初にその属性があるかどうかを検索しますが、foo の場合は独自のプロトタイプは検索しません。が見つからない場合、obj はプロトタイプ チェーンに沿って順番に検索します...

上の例では、f のプロトタイプに foo 属性を定義し、obj はプロトタイプ チェーンでこの属性を見つけて実行します。


最後に、この記事に含まれる重要なポイントをいくつかの文で要約します:

  1. プロトタイプ チェーンの形成は、実際には、プロトタイプではなく __proto__ に依存します。JS エンジンがオブジェクトのメソッドを実行するときは、最初にオブジェクト自体を検索します。メソッドが存在するかどうか、存在しない場合はプロトタイプ チェーン上で検索されますが、独自のプロトタイプは検索されません。

  2. オブジェクトの __proto__ は独自のプロトタイプ チェーンを記録し、独自のデータ型を決定します。__proto__ を変更することは、オブジェクトのデータ型を変更することと同じです。

  3. 関数のプロトタイプは、それ自体のプロトタイプ チェーンに属しません。これは、サブクラス作成の中核であり、サブクラスのデータ型を決定し、サブクラスのプロトタイプ チェーンを接続するブリッジです。

  4. プロトタイプ オブジェクトのメソッドとプロパティを定義する目的は、サブクラスによって継承され、使用されることです。


ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!