ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptにおける__proto__とプロトタイプの関係を深く理解する_基礎知識

JavaScriptにおける__proto__とプロトタイプの関係を深く理解する_基礎知識

WBOY
WBOYオリジナル
2016-05-16 17:47:26857ブラウズ

ここでは、オブジェクトの内部プロトタイプ (__proto__) とコンストラクターのプロトタイプ (prototype) の関係について説明します。
1. すべてのコンストラクター/関数の __proto__ は、空の関数 (空の関数) である Function.prototype を指します

コードをコピーします コードは次のとおりです。

Number.__proto__ === Function.prototype // true
Boolean.__proto__ === Function.prototype // true
文字列。 __proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
Array.__proto__ === 関数. プロトタイプ // 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__ === オブジェクト.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 のタイプが「function」である唯一のプロトタイプでもあります。他のコンストラクターのプロトタイプはオブジェクトです。以下のように
コードをコピー コードは次のとおりです。

console.log(typeof Function.プロトタイプ) // 関数
console.log(typeof Object.prototype) // オブジェクト
console.log(typeof Number.prototype) // オブジェクト
console.log(typeof Boolean.prototype) // オブジェクト
console .log(typeof String.prototype) // オブジェクト
console.log(typeof Array.prototype) // オブジェクト
console.log(typeof RegExp.prototype) // オブジェクト
コンソール。 log(typeof Error .prototype) // オブジェクト
console.log(typeof Date.prototype) // オブジェクト
console.log(typeof Object.prototype) // オブジェクト

ああ、それは上でも述べられていますが、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 = 新しい日付
var err = new Error('例外')
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 の内部プロトタイプは常にそのインスタンス オブジェクトを指します。コンストラクターのプロトタイプ。
各オブジェクトにはコンストラクターを取得できるコンストラクター属性があるため、次の出力結果も同じです。
コードをコピー コードは次のとおりです:

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 に代入されるのは、オブジェクト リテラル メソッドを使用して定義されたオブジェクトのコンストラクターが、ルート コンストラクターを指します。 Object.prototype は空のオブジェクト {} であり、{} は当然のことながら {getName: function(){}} とは異なります。次のように

コードをコピーします コードは次のとおりです:
var p = {}
console.log (Object.prototype) // 空のオブジェクトです {}
console.log(p.constructor === Object) // オブジェクト リテラル モードで定義されたオブジェクトのコンストラクターは Object
console.log(p .constructor.prototype === Object.prototype) // true の場合、説明はありません

上記のコードで使用されている __proto__ は現在 IE6 ではサポートされていません/ 7/8/9。 IE9 では、Object.getPrototypeOf(ES5) を使用してオブジェクトの内部プロトタイプを取得できます。

コードをコピー コードは次のとおりです。
var p = {}
var __proto__ = Object .getPrototypeOf(p)
console.log(__proto__ === Object.prototype) // true

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。