JavaScript では、関数はプロパティとメソッドを含むFunction
型のオブジェクトです。プロトタイプ(Prototype)
は、 Function
型オブジェクトの属性です。
prototype
属性は関数の定義時に含まれ、その初期値は空のオブジェクトです。 JavaScript の関数にはプロトタイプの型が定義されていないため、プロトタイプは任意の型にすることができます。
プロトタイプは、オブジェクトの共有プロパティとメソッドを保存するために使用されます。プロトタイプのプロパティとメソッドは、関数自体のプロパティとメソッドには影響しません。
// Function タイプのプロパティ -> すべての関数が持つプロパティ console.log(Function.prototype) //[Function] //関数を定義 function fn() { console.log('これは関数です'); } //プロトタイプのデフォルト値は空のオブジェクトです console.log(fn.prototype) //fn {} // 関数にはコンストラクターが含まれています --> すべての参照型は実際にはコンストラクターです console.log(Number.prototype) //[Number: 0] console.log(Object.prototype);//{}
共有プロパティとメソッドを設定する次の 2 つの方法で、オブジェクトのプロトタイプを取得できます。
prototype
属性を使用する方法getPrototype
使用する方法です。 Object オブジェクト (obj) メソッドの。関数 fn() { console.log('これは関数です'); } //アクセス オブジェクトの属性構文構造を使用します console.log(fn.prototype) //fn {} console.log(fn['プロトタイプ']);//fn {} //オブジェクト型は getPrototypeOf() メソッドを提供します console.log(Object.getPrototypeOf(fn)); //[関数]
Object.getOwnPropertyDescriptors()
メソッドは、オブジェクトのすべての独自のプロパティの記述子を取得するために使用されます。
var result = Object.getOwnPropertyDescriptor(Object.prototype,'constructor'); console.log(result) //出力結果は以下の通りです。 //{ // 値: [関数: オブジェクト], // 書き込み可能: true, // 列挙可能: false, // 設定可能: trueコンストラクターは
、
constructor是在创建函数的时候自动添加的,指向构造函数本身
は、次の 2 つの方法で設定できます。
Constructor.prototype.Attribute name = 属性値; Constructor.prototype.Method name = function(){};
プロトタイプに多くの属性を追加する必要がある場合、
构造函数.prototype.属性名
何度も記述するのは面倒ですが、prototype
全体を直接変更できます
。constructor.prototype = { 属性名: 属性値、 メソッド名: function(){}}
function foo () {}foo.prototype = { コンストラクター: foo, 名前:「ジャム」、 年齢:18歳、 address: 'Beijing'}var fn = new foo()console.log(fn.address) //Beijing
各オブジェクトにはisPrototypeOf()
メソッドがあり、このメソッドはオブジェクトが別のオブジェクトのプロトタイプ。
サンプルコードは次のとおりです。 // 初期化子を通じてオブジェクトを定義します var obj = { 名前:「ジャム」 } //コンストラクター関数 Hero() を定義 {} // オブジェクト obj をコンストラクター Hero Hero のプロトタイプに代入します Hero.prototype = obj; // コンストラクターを通じてオブジェクトを作成します var hero = new Hero(); // isPrototypeOf() メソッドは、指定されたオブジェクトが別のオブジェクトのプロトタイプであるかどうかを判断します。 var result = obj.isPrototypeOf(hero); console.log(result);//true は
、
obj
オブジェクトがhero
オブジェクトのプロトタイプであることを検証します。
次に、コードを使用してプロトタイプ チェーンの理解を深めます
。 : obj オブジェクト上のオブジェクトを検索します。 address 属性 js によって実行されるステップ: 1. get 操作がトリガーされます。 2. 現在のオブジェクト内の属性を検索します。 3. 見つからない場合は、この時点でプロトタイプ チェーン (__proto__) オブジェクトを検索します。見つからない場合は、最上位のプロトタイプが見つかるまで、プロトタイプ チェーンに沿って検索を続けます (最上位のプロトタイプが何であるかは一時的に不明です)。
1.1
名前:「ジャム」、 年齢: 19 } /* 要件: obj オブジェクトの address 属性を検索します*/ // プロトタイプ チェーンはレイヤーごとに検索され、見つからない場合は、最上位のプロトタイプが見つかるまで検索されます。 obj.__proto__.__proto__ = {} obj.__proto__.__proto__.__proto__ = { 住所:「北京」 } console.log(obj.address) // 北京 console.log(obj.__proto__.__proto__.__proto__) // { address: '北京' }
次に、最後にアドレス属性を見つけます
那么这里有一个问题,如果一直没有查到,会无穷尽的去查找吗?接下来我们就来了解一下
。
那么这里有一个问题,如果一直没有查到,会无穷尽的去查找吗?接下来我们就来了解一下
上で述べたように、プロトタイプ チェーンに沿って際限なく検索することはありません。最上位のプロトタイプが見つかった場合、まだ見つかっていない場合はundefined
が返されます。
では、トップレベルのプロトタイプとは何でしょうか?
サンプル コードは次のとおりです。
var obj = { name: 'jam' }console.log(obj.__proto__) // {}console.log(obj.__proto__.__proto__) //
null リテラル オブジェクト obj のプロトタイプは次のとおりです。
{}
。{}
最上位プロトタイプです。__proto__
上向きに出力し続けると、null 値が返されます。これは、前の層がすでに最上位プロトタイプであることを示しています。
次の図は、最上位プロトタイプの補足です。コードの最初の部分に欠落しています:
顶层原型就是Object.prototype
3.1 では、プロトタイプ チェーンの終点はどこでしょうか?たとえば、3 番目のオブジェクトにもプロトタイプ__proto__
属性がありますか?
var obj = {name:'jam'}obj.__proto__ = {}obj.__proto__.__proto__ = {}obj.__proto__.__proto__.__proto__ = {}console.log(obj.__proto__.__proto__.__proto__.__proto__) // {}
上記の出力結果は空对象{}
var obj = { 名前:「ジャム」、 年齢: 19 } console.log(obj.__proto__) // {} console.log(Object.prototype) // {} console.log(obj.__proto__ === Object.prototype) // true
Object はすべてのクラスの親クラスであるため、obj.__proto__ は実際には Object.prototype です。
console.log(obj.__proto__ === Object.prototype) // true
結果の Object.prototype がトップレベルのプロトタイプであることがわかります。
{}
です。3.2 次に、次のようになります。 : {}
プロトタイプについて何か特別なことはありますか?
console.log(obj.__proto__.__proto__.__proto__.__proto__.__proto__) // null
Object.prototype
{} ですが、それは空ではありませんが、内部のプロパティは列挙可能ではありません。たとえば、 constructor
を出力してみましょう。参照するプロパティ<!-- コンストラクター属性があり、空ではないことがわかります -->console.log(Object.prototype.constructor) // [関数: オブジェクト] <!-- コンストラクターは参照しますObject -->
Object.getOwnPropertyDescriptors()
メソッドを使用してObject.prototype
内のすべての独自のプロパティの記述子を取得することもできます。 console.log(Object.getOwnPropertyDescriptors(Object.prototype)) //以下の長いスクリーンショットに示すように