マスターオブジェクト🍨 第2部
13688 ワード
オブジェクトとプロトタイプ
多くのオブジェクト指向言語のように、JavaScriptは実装継承のサポートを提供します:ダイナミックな委任メカニズムを通してコードまたはデータの再利用.しかし、多くの従来の言語とは異なり、JavaScriptの継承メカニズムはクラスよりむしろプロトタイプに基づいています.多くのプログラマにとって、JavaScriptはクラスなしで遭遇する最初のオブジェクト指向言語です.
多くの言語では、すべてのオブジェクトは関連するクラスのインスタンスです.そして、それはすべてのそのインスタンスの間で共有されるコードを提供します.JavaScriptは対照的に、クラスの組み込み概念を持っていません.代わりに、オブジェクトは他のオブジェクトから継承します.すべてのオブジェクトは、そのプロトタイプとして知られているいくつかの他のオブジェクトに関連付けられています.伝統的なオブジェクト指向言語からの多くの概念がまだ引き継ぐけれども、プロトタイプで働くことはクラスと異なることができます.
違いを理解する
prototype
, getPrototypeOf
and __proto__
プロトタイプは3つの別々であるが関連したアクセッサを含んでいます.この不幸な重なりは、かなりの混乱に自然につながる.要点をまっすぐにしましょう.C.prototype
はnew C ()が作成したオブジェクトのプロトタイプを確立するために使用されます.Object.getPrototypeOf(obj)
検索のための標準ES 5メカニズムobj
’sプロトタイプオブジェクト.obj.__proto__
検索のための非標準メカニズムobj
’sプロトタイプオブジェクトそのオブジェクトを作成します.
function User(name, passwordHash) {
this.name = name;
this.passwordHash = passwordHash;
}
User.prototype.toString = function () {
return "[User " + this.name + "]";
};
User.prototype.checkPassword = function (password) {
return hash(password) === this.passwordHash;
};
let u = new User("sfalken", "0ef33ae791068ec64b502d6cb0191387");
ユーザー関数には、既定のプロトタイププロパティが付属しており、空または複数の空を開始するオブジェクトが含まれます.この例では、User.prototype
対象:toString
and checkPassword.
新しい演算子を使用してユーザーのインスタンスを作成すると、結果のオブジェクトUはUser.prototype
自動的にプロトタイプオブジェクトとして割り当てられます.下の画像は、これらのオブジェクトの図を示しますインスタンスオブジェクトUをプロトタイプオブジェクトにリンクしている矢印に注目してください
User.prototype
. このリンクは継承関係を示します.プロパティの検索は
object
’s own properties
; 例えば、米国の名前とu.passwordHash
uに直接見つからないUプロパティの即時プロパティの現在の値をUのプロトタイプで調べます.アクセスu.checkPassword
, たとえば、User.prototype
.これは私たちのリストの次の項目につながる.コンストラクタ関数のプロトタイププロパティを使用して、新しいインスタンスのプロトタイプ関係を設定します
Object.getPrototypeOf()
缶既存のオブジェクトのプロトタイプを取得するために使用します.したがって、例えば、上記の例でオブジェクトUを作成した後にテストすることができます.
Object.getPrototypeOf(u) === User.prototype; // true
This illustrates the prototype relationships for the User constructor and
instance.
いくつかの環境は検索のための非標準メカニズムを生成する
特別なものを通しての物体の原型
__proto__
プロパティ.これはES 5のサポートしていない環境のための一時停止として役に立つ
Object.getPrototypeOf
. このような環境では、同様にテストすることができます.u.__proto__ === User.prototype; // true
プロトタイプの関係についての最終的な注意:JavaScriptプログラマは、しばしば、それが機能より少し多くであるとしても、クラスをクラスとして説明するでしょう.JavaScriptのクラスは、基本的にコンストラクタ関数(ユーザ)とクラスのインスタンス間でメソッドを共有するために使用されるプロトタイプオブジェクトの組み合わせですUser.prototype
).This is a conceptual view of the User “class”.
上記のイメージは、ユーザークラスを概念的に考える良い方法を提供します.ユーザー関数は、クラスのパブリックコンストラクターを提供します
User.prototype
インスタンス間で共有されるメソッドの内部実装です.ユーザーとUの通常の使用は、直接プロトタイプオブジェクトにアクセスする必要はありません.覚えていること🧠
C.prototype
新しく作成したオブジェクトのプロトタイプを決定するC()
. Object.getPrototypeOf(obj)
オブジェクトのプロトタイプを取得するための標準ES 5関数です.obj.__proto__
オブジェクトのプロトタイプを取得するための非標準メカニズムです.関連プロトタイプ.
好む
Object.getPrototypeOf
to __proto__
🦄ES 5導入
Object.getPrototypeOf
オブジェクトのプロトタイプを検索するための標準APIとして、JavaScriptエンジンの多くの後にのみ__proto__
同じ目的のプロパティ.しかし、すべてのJavaScript環境がこの拡張モジュールをサポートしているわけではない.環境は、例えば、ヌルプロトタイプを有するオブジェクトの処置に関して異なる.いくつかの環境ではObject.prototype
, したがって、nullプロトタイプを持つオブジェクトには特別なPropertyプロパティはありません.var empty = Object.create(null); // object with no prototype
"__proto__" in empty; // false (in some environments)
// In others, __proto__ is always handled specially, regardless of an object’s state:
var empty = Object.create(null); // object with no prototype
"__proto__" in empty; // true (in some environments
どこObject.getPrototypeOf
利用可能な、それはプロトタイプを抽出するためのより標準的でポータブルなアプローチです.また、__proto__
プロパティは、その汚染のためにバグの数につながるすべてのオブジェクト.現在拡張機能をサポートしているJavaScriptエンジンは、これらのバグを避けるために、プログラムを無効にすることを将来的に選ぶかもしれません.好む
Object.getPrototypeOf
コードが動作し続けても、__proto__
無効です.ES 5 APIを提供しないJavaScript環境のために、それは4の条件で実装するのが簡単です
__proto__
:if (typeof Object.getPrototypeOf === "undefined") {
Object.getPrototypeOf = function (obj) {
var t = typeof obj;
if (!obj || (t !== "object" && t !== "function")) {
throw new TypeError("not an object");
}
return obj.__proto__;
};
}
This implementation is safe to include in ES5 environments, because it avoids installing the function if
Object.getPrototypeOf
already exists.
覚えていること🧠
Object.getPrototypeOf
非標準
__proto__
プロパティ.Object.getPrototypeOf
非ES 5環境でサポート
__proto__
. 修正する
__proto__
🍕特別なProtoプロパティは、追加のパワーを提供します
Object.getPrototypeOf
オブジェクトのプロトタイプリンクを変更する機能.この力は無邪気に見えるかもしれませんが(結局のところ、それはちょうど別の財産です.)それは実際に重大な意味を持ち、避けなければならない.変更を避ける最も明白な理由__proto__
移植性はすべてのプラットフォームでサポートされていますオブジェクトのプロトタイプを変更するだけで、それを行うポータブルコードを書くことができません.
変更を避けるもう一つの理由
__proto__
パフォーマンスです.JavaScriptプログラムは、JavaScriptプログラムが実行する最も一般的な操作のいくつかであるので、すべての最新のJavaScriptエンジンは、オブジェクトプロパティの取得および設定の方法を大きく最適化します.これらの最適化は、オブジェクトの構造のエンジンの知識に基づいて構築されます.オブジェクトの内部構造を変更すると、オブジェクトまたはオブジェクトにそのプロパティを追加または削除することによって、そのプロトタイプのチェーン内のオブジェクトを変更すると、これらの最適化の一部が無効になります.修飾__proto__
実際に継承構造自体を変更します.これは通常のプロパティへの変更よりも多くの最適化を無効にすることができます.しかし、修正を避ける最大の理由
__proto__
予測可能な動作を維持するためです.オブジェクトのプロトタイプチェーンは、プロパティとプロパティ値の集合を決定することによってその動作を定義します.オブジェクトのプロトタイプリンクを変更することは、それに脳移植を与えるようです.そのような操作が役に立つかもしれない例外的な状況を想像することは可能かもしれません、しかし、基本的な健全性の問題として、継承階層は安定していなければなりません.カスタムプロトタイプリンクを使用して新しいオブジェクトを作成するには
Object.create
. ES 5を実装しない環境のために、アイテム33はポータブルObject.create
それは当てにならない__proto__
.覚えていること🧠
__proto__
プロパティ.Object.create
新しいオブジェクトのカスタムプロトタイプを提供します.🎉🎉🎉 この記事の第2部を読んでくれてありがとう!🎉🎉🎉
このSERIEの3番目の部分をチェックアウトすることを忘れないでください!🥳 Make your Constructors new-Agnostic .
あなたの好きなプログラミング言語についての深さの知識の詳細についてはblog オンデマンド開発者になる😉, そして、あなたは同様に私を見つけることができます😃.
Reference
この問題について(マスターオブジェクト🍨 第2部), 我々は、より多くの情報をここで見つけました https://dev.to/jrmatanda/master-objects-in-js-part-2-2fnnテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol