JavaScriptにおけるプロトタイプ, Chern - Radise - Countとプロトタイプ継承


This post was originally published on my website


JavaScriptでいくつかの時間を費やしている場合は、可能性が既に見られているか、または少なくともプロトタイプについて聞いたことです.あなたがプロトタイプについて不明であるか、それがすることをするならば、この記事はちょうどあなたのためです.この記事では、JavaScriptプロトタイプの作業を理解し、その過程で、プロトタイプの継承とどのように動作するかを説明しようとします.
開始する前に、JavaScriptのすべてが高レベルのオブジェクトであることを既に認識していることを願っています.これが意味するのはNULLと未定義を除いて、JavaScriptのすべてはObject .

But Varun, how is that possible? We have several primitives in JavaScript like String, Number, Boolean etc. How can a data type, say Number, be derived from Object?



原型と胡桃
そのためには、まずプロトタイプを理解する必要がある.JavaScriptのプロトタイプは、オブジェクトが保持している特別なプロパティのセットではありませんObject ). 各オブジェクトはそれ自身のセットを保持しますprototype プロパティ.私がそれによって意味するものの非常に基本的な例を見ましょう.あなたのブラウザーdevツールを開けて、あなたが行こうとしてスニペットをためしてください.
var fooFunc = function() {
    return {
        foo: 42
    }
};
fooFunc.prototype.bar = 'baz';
var fooVal = fooFunc();
console.log(fooVal);   // {foo: 42}
console.log(fooFunc.prototype);     // {bar: "baz", constructor: ƒ}
番目の印刷文では、すべての美しさのプロトタイプの継承の例を提供します.機能fooFunc に由来するObject インスタンスとそれ自身のプロパティのセットです.{bar: baz} それがどのようなものであってもObject すなわち{constructor: ƒ} .

So if fooFunc is derived from Object, can I go up the chain and see Object's prototype?


良い質問と絶対にすることができます.しかし、1つのことを念頭に置いておく必要があること以外はfunction タイプ、オブジェクトの他のすべてのプロトタイプはそれの中にあります__proto__ プロパティ.それがどういう意味か見てみよう.
console.log('prototype of fooFunc:');
console.log(fooFunc.prototype);     // {bar: "baz", constructor: ƒ}
console.log('prototype of Object:');
console.log(fooFunc.prototype.__proto__);   // {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
何を見ていますか.最後のconsoleステートメントは、それ自身の特別なプロパティの集合を持つオブジェクトを返します.これは2000年のプロトタイプチェーンにすぎないObject . これは、我々が実際にプロトタイプチェーンとその機能を横断することができることを確認しますfooFunc に由来するObject .

So what happens when I try to traverse the prototype chain of Object?


何が起こるか見ましょう
console.log(fooFunc.prototype); // {bar: "baz", constructor: ƒ}
console.log(fooFunc.prototype.__proto__);// {constructor: ƒ, __defineSetter__: ƒ, …}
console.log(fooFunc.prototype.__proto__.__proto__);     // null
そうですね.Object JavaScriptではトップレベルの構成です.プロパティを参照してくださいObject 's親の場合、親がいないので、NULLを取得しますObject .
この点で、私はあなたが始めに戻って、私がポストで以前に言ったものにここまですべてを関連させたいです.

Prototpyes in JavaScript are nothing but a special set of properties held by an object.



原型継承
プロトタイプがどのように動作するかを理解したので、プロトタイプの継承はかなりまっすぐにするべきです.以下の例を見てみましょう.
var obj = function(){
    this.firstName = 'Varun';
    this.lastName = 'Dey'
}
obj.prototype.age = 25;
var nameObj = new obj()
console.log(nameObj.age);   // 25
ここで起こっていることを打破しよう.
  • 最初に、我々は機能を定義しているobj .
  • 今、我々はまた別のプロパティを割り当てているage 直接にobj 'sのプロトタイプチェーン.
  • 変数名をインスタンス化しますnameObj からobj . nameObj に2つのプロパティを追加するオブジェクトです.firstName and lastName .
  • 私が尋ねるときnewObj 何故ならage プロパティは、最初にそれ自身のオブジェクトに入り、それを見つけようとします.見つけるかage インnameObj オブジェクト?
  • いいえ、それはチェーンを上がりますnameObj.__proto__ そして、age そのオブジェクト内のプロパティ.
  • それはage プロパティnameObj.__proto__ と全く同じですobj.prototype .
  • そして、これはJavaScriptの原型の継承がすべてであることです.JavaScriptを使用してキーを取得する場合は、まず最初にそれを自分のオブジェクトのプロパティに調べます.それが何も見つけられないならば、それはそのプロトタイプのチェーンに行きますobj.__proto__ ) そして、それらのプロパティの中でそのキーを見つけようとすると、そこで見つからなければ、現在のプロトタイプ型のチェーンになりますobj.__proto__.__proto__ ) そして、同じことをします.それは、同じプロセスを繰り返すまで続けますObject 'それがそこでさえ見つけることができないならば、sプロトタイプチェーンとそこから未定義のリターン.

    公害
    JavaScriptでは、Java/C++のような他のクラスベースの言語とは全く異なります.
    function parent(){
        return{
            foo: 42,
            bar: 'baz'
        }
    }
    child = new parent()
    
    あなたがよく見るならば、あなたはそれを見ますchild のインスタンス化されたオブジェクトparent . And parent 最終的にはObject . これはどういう意味ですかchild 'とparent 'SプロトタイププロトタイプはObject 'プロトタイプ
    child.__proto__ === parent.prototype.__proto__      // true
    
    もう一つの例を見てみましょう.
    function parent(){
        return{
            foo: 42,
            bar: 'baz'
        }
    }
    parent.prototype.__proto__.baz = 'I should not belong here'
    child = new parent()
    console.log(child.__proto__)
    
    ここでは、プロトタイプの汚染の主要な例を参照してください.プロパティを作成baz 直接にObject '機能のプロトタイプチェーンを越えることによるsプロトタイプ.現在bazObject そのため、コンソールステートメントを参照してくださいObject プロパティは、我々も今baz: "I should not belong here" . これは悪い習慣です、そして、それがカプセル化を壊すので、眉をひそめています.
    同様に私もこれを行うことができます.
    function parent(){
        return{
            foo: 42,
            bar: 'baz'
        }
    }
    delete parent.prototype.constructor
    child = new parent()
    

    パフォーマンス
    言うまでもないが、あなたのProrototypeチェーンを横断して、ルックアップ時間は増加します、そして、したがって、パフォーマンスは苦しみます.これは、完全なプロトタイプチェーンを越えて存在しないプロパティにアクセスしようとしたときに重要になります.必要なプロパティがオブジェクト自体で定義されているかどうかを確認するには、hasOwnProperty .
    child.hasOwnProperty('foo');    // true
    parent.hasOwnProperty('baz');   // false
    Object.prototype.hasOwnProperty('baz'); // true
    

    サークル完成
    最初に、私はNULLと未定義を除いてObject インスタンス化.そのことを証明しましょう.
    const foo = 42;
    const bar = 'fooBar';
    const baz = true;
    foo.__proto__.__proto__ === bar.__proto__.__proto__;    // true
    bar.__proto__.__proto__ === baz.__proto__.__proto__;    // true
    
    それで、あなたは私が何を言っているかについて見ます.JavaScriptのほとんどすべてがObject
    結論
    プロトタイプはJavaScriptの基本的なブロックになります.JavaScriptでどのようなプロトタイプが機能しているかを理解できるようになりました.したら、それを適切にハングアップするには、この知識を拡張する方法を理解することができますてthis JavaScriptで動作します.Mozillaはこれに優れたリソースを持っています.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
    JavaScriptをよりよく理解するのにこの記事が役に立ちますか?