ホームページ > 記事 > ウェブフロントエンド > JavaScript における __proto__ とプロトタイプの関係の簡単な分析
今回は JavaScript における __proto__ とプロトタイプの関係について簡単に分析します。以下は実際のケースです。エディターに従ってご覧ください。
1. すべてのコンストラクター/関数の __proto__ は、空の関数である Function.prototype を指します (Empty function)
Number.__proto__ === Function.prototype // true Boolean.__proto__ === Function.prototype // true String.__proto__ === Function.prototype // true Object.__proto__ === Function.prototype // true Function.__proto__ === Function.prototype // true Array.__proto__ === Function.prototype // true RegExp.__proto__ === Function.prototype // true Error.__proto__ === Function.prototype // true Date.__proto__ === Function.prototype // true
JavaScript には合計 12 個の組み込み (ビルトイン) コンストラクター/オブジェクトがあります (JSON は ES5 で新たに追加されました)。アクセス可能なコンストラクターは以下の 8 つです。 Global などの残りの部分には直接アクセスできません。引数は関数が呼び出されたときに JS エンジンによってのみ作成されます。Math、JSON はオブジェクトの形式で存在し、新しいものは必要ありません。それらの __proto__ は Object.prototype です。以下の通り
Math.__proto__ === Object.prototype // true JSON.__proto__ === Object.prototype // true
上記の「すべてのコンストラクター/関数」には、確かにカスタムのものも含まれます。以下の通り
// 函数声明 function Person() {} // 函数表达式 var Man = function() {} console.log(Person.__proto__ === Function.prototype) // true console.log(Man.__proto__ === Function.prototype) // true
これはどういう意味ですか?
ルート コンストラクターの Object や Function 自体も含め、すべてのコンストラクターは Function.prototype から取得されます。すべてのコンストラクターは Function.prototype のプロパティとメソッドを継承します。長さ、呼び出し、適用、バインドなど (ES5)。
Function.prototype は、XXX.prototype の唯一のタイプでもあります。 「関数」のプロトタイプ。他のコンストラクターのプロトタイプはオブジェクトです。例:
console.log(typeof Function.prototype) // function console.log(typeof Object.prototype) // object console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object console.log(typeof String.prototype) // object console.log(typeof Array.prototype) // object console.log(typeof RegExp.prototype) // object console.log(typeof Error.prototype) // object console.log(typeof Date.prototype) // object console.log(typeof Object.prototype) // object
ああ、これが空の関数であることも上で説明しましたが、alert(Function.prototype) を見てみましょう。
すべてのコンストラクター (組み込みおよびカスタムを含む) の __proto__ が Function.prototype であることがわかったので、Function.prototype の __proto__ は誰でしょうか?
JavaScript の関数も第一級市民であることを皆さんも聞いたことがあると思いますが、これをどのように示すことができますか?以下に示すように
console.log(Function.prototype.__proto__ === Object.prototype) // true
これは、すべてのコンストラクターも通常の JS オブジェクトであり、コンストラクターに属性を追加/削除できることを示しています。同時に、Object.prototype のすべてのメソッド (toString、valueOf、hasOwnProperty など) も継承します。
最後に、Object.prototype の __proto__ は誰ですか?
Object.prototype.__proto__ === null // true
はトップに到達しましたが、nullです。
2. すべてのオブジェクトの __proto__ は、そのコンストラクターのプロトタイプを指します
上記では、すべての組み込みコンストラクターとカスタム コンストラクターの __proto__ をテストしました。これらすべてのインスタンス オブジェクトの __proto__ を見てみましょう。 _proto__ は誰を指すのでしょうか?
まず JavaScript エンジンの組み込みコンストラクターを見てください
var obj = {name: 'jack'} var arr = [1,2,3] var reg = /hello/g var date = new Date var err = new Error('exception') console.log(obj.__proto__ === Object.prototype) // true console.log(arr.__proto__ === Array.prototype) // true console.log(reg.__proto__ === RegExp.prototype) // true console.log(date.__proto__ === Date.prototype) // true console.log(err.__proto__ === Error.prototype) // true
次に、カスタム コンストラクターを見てください。ここで Person が定義されています
function Person(name) { this.name = name } var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true
p は Person のインスタンス オブジェクトであり、p の内部プロトタイプは常に を指します。コンストラクター Person のプロトタイプ。
各オブジェクトはコンストラクタ属性を持ち、そのコンストラクタを取得できるので、以下の印刷結果も同一です
function Person(name) { this.name = name } var p = new Person('jack') console.log(p.__proto__ === p.constructor.prototype) // true
上記の人はプロトタイプに属性やメソッドを追加していませんが、ここではプロトタイプにgetNameメソッドを追加しています
function Person(name) { this.name = name } // 修改原型 Person.prototype.getName = function() {} var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // true
p.__proto__、Person.prototype、および p.constructor.prototype はすべて同一である、つまり、すべて同じオブジェクトを指していることがわかります。
プロトタイプを別の方法で設定した場合、結果は少し異なります
function Person(name) { this.name = name } // 重写原型 Person.prototype = { getName: function() {} } var p = new Person('jack') console.log(p.__proto__ === Person.prototype) // true console.log(p.__proto__ === p.constructor.prototype) // false
person.prototypeはここで直接書き換えられています(注: 前の例はプロトタイプを変更するものです)。出力は、p.__proto__ がまだ p.constructor.prototype ではなく Person.prototype を指していることを示しています。
これも分かりやすいですが、 person.prototype に代入されるのはオブジェクトリテラル {getName: です。 function(){}}、オブジェクト リテラル メソッドを使用して定義されたオブジェクトのコンストラクターは、ルート コンストラクター Object を指します。Object.prototype は空のオブジェクトです。{}、{} は当然のことながら {getName: と同じです。 function(){}} は等しくありません。以下の通り
var p = {} console.log(Object.prototype) // 为一个空的对象{} console.log(p.constructor === Object) // 对象直接量方式定义的对象其constructor为Object console.log(p.constructor.prototype === Object.prototype) // 为true,不解释
上記のコードで使用されている __proto__ は、現在 IE6/7/8/9 ではサポートされていません。 IE9 では、Object.getPrototypeOf(ES5) を使用してオブジェクトの内部プロトタイプを取得できます。
りー以上がJavaScript における __proto__ とプロトタイプの関係の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。