関数を定義すると、関数自体にデフォルトでプロトタイプ属性が設定されますが、new 演算子を使用してオブジェクトを生成した場合、プロトタイプ属性は存在しません。これを説明するための例を見てみましょう。
関数a( c){
this.b = c;
this.d =function(){
alert(this.b);
}
var obj = new a( 'test');
alert(typeof obj.prototype);//undefine
alert(typeof a.prototype);//object
からわかるように、上の例では、prototype 属性はオブジェクトを指します。以下の図を参照してください。
a.prototype には 2 つの属性が含まれており、1 つはコンストラクター、もう 1 つは __proto__
このコンストラクターはコンストラクター a であり、これも理解しやすいです。
それで、__proto__ とは何ですか?
これには、プロトタイプ チェーンの概念が含まれます:
各オブジェクトは、その内部の属性 (__proto__) を初期化します。オブジェクトの属性にアクセスするとき、この属性がオブジェクト内に存在しない場合、この __proto__ 属性でそれを探します。独自の __proto__ があるので、それを探し続けました。
mozzlia の説明を参照してください
オブジェクトが作成されると、その プロパティは構築関数の __proto__
プロパティに設定されます。たとえば、prototype
は var fred = new Employee();
.fred.__proto__ = Employee.prototype;
を引き起こします。
これは、オブジェクト内で直接宣言されていないプロパティを検索するために実行時に使用されます。たとえば、 が fred.doSomething()
を含まない場合、fred
がチェックされます。 doSomething
を含む fred.__proto__
を指します。つまり、Employee.prototype
が呼び出されます。doSomething
fred.__proto__.doSomething()
はインスタンスのプロパティであるのに対し、 はコンストラクター関数のプロパティであることに注意してください。<em>__proto__</em>
prototype
信じるか信じないかは別として、写真を見てみましょう
alert(obj.__proto__ === a.prototype) を追加した場合 //true
同様に、ここでは新しい演算子が何を行うかを分析します
var obj={}; つまり、オブジェクト obj を初期化します。
obj.__proto__=a.prototype;
- a.call(obj); つまり、obj の構築は obj の初期化とも言えます。
-
-
この例をもう少し複雑にするために変更してみましょう。
function a(c){
this.b = c;
this.d =function(){
alert(this.b);
}
a.prototype.test = function(){
alert(this.b);
}
var obj = function (){}
obj.prototype = new a('test');
obj.prototype.test1 =function() {
alert(22222);
}
var t = new obj('test');//alert('test'); >
このプロセスを分析してみましょう
var t = new obj('test'); から t.__proto__ = obj.prototype を取得できますが、上記では obj.prototype =new a('test' と指定されています) ) ; 次のように見ることができます
obj.prototype = p, p = new a('test'); p.__proto__ = a.prototype;
次に、obj.prototype を示します。 __proto__ = a .prototype、t.__proto__ = obj.prototype から、t.__proto__.__proto__ = a.prototype、
と結論付けることができます。したがって、オブジェクト t は最初に独自のプロトタイプを探して、そこに存在するかどうかを確認します。テスト関数がないことが判明した場合、結果は上位レベル、つまり t.__proto__、つまり obj.prototype に移動してテスト関数を見つけますが、obj.prototype にはテスト関数がありません。この機能を使用して上位を検索します。つまり、
t.__proto__.__proto__ が見つかります。 t.__proto__.__proto__ = a.prototype なので、このメソッドは a.prototype で見つかり、alert('test') が出力されます。
ここから js のプロトタイプチェーンの本質は __proto__ にあると分析して結論付けることができます
別の例を見てください
コードをコピー
コードは次のとおりです:
関数 a(c){
this.b = c;
this.d =function(){
alert(this.b);
}
var obj = new a('test');
alert(obj.constructor);//function a(){}
alert(a.prototype.constructor);//function a() {}
上記の __proto__ に従って、まず、obj には属性コンストラクターがありませんが、obj.__proto__ = a.prototype; から始めます。 🎜>a .prototype で検索すると、a.prototype.constructor は単なる a なので、両方の結果は同じになります。