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 が関数オブジェクトではなく、通常のオブジェクトであるため、明らかにそうではありません。
関数オブジェクトと通常のオブジェクトを簡単に理解した後、JavaScript のプロトタイプとプロトタイプ チェーンを見てみましょう。
JS では、関数オブジェクト f1 が作成されるたびに、プロトタイプや __proto__ などのいくつかのプロパティがオブジェクトに組み込まれます。Prototype は、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__ は null となり、obj オブジェクトのプロトタイプを示します。 . チェーンの終わり。以下に示すように:
obj オブジェクトがそのようなプロトタイプチェーンを持った後、obj.foo が実行されると、obj は最初に属性を持っているかどうかを検索しますが、foo が見つからない場合、obj はプロトタイプに従います。チェーンして検索してください...
上記の例では、f のプロトタイプに foo 属性を定義しました。このとき、obj はプロトタイプ チェーン上でこの属性を見つけて実行します。
最後に、この記事に含まれる重要なポイントをいくつかの文でまとめます:
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。