JavaScriptのプロトタイプとconstructor、_uproto_、prototypeの関係


前言
まず、なぜJavaScriptの原型を明らかにしたかというと、これがJSの根です.JavaScriptは伝統的な対象言語ではないですが、自分の種類と継承メカニズムがあります.一番重要なのは原型を採用した概念です.JSは対象に向かうというより、モデルに向かうというほうがいいです.JSという言葉は開発当初から原型に基づいてものを作っています.対象に向けた思想ですが、あくまでも原型に向かう原理です.操作上もそうです.
私たちの先生は以前、何年間働いている人たちは、この問題ではどっちつかずだと言いました.基礎こそはプログラマの上限を決める最終指標です.一つの言語の基礎をしっかりと身につけることで、新しいものを原生の言語で開発することができます.枠もプラグインもいいです.しかし、基礎がよくないなら、他の人が開発したものを使ってもいいです.自分で開発する能力はありません.
原型を知るためには、知識の点が多いです.構造関数、指針、対象、継承という概念は敷居がありますが、あせらないでください.一口では大きなデブを食べられません.私は「JavaScript高編」と各種資料を読んでから、自分のこの部分に対する理解をまとめました.一貫性と分かりやすい方法で説明します.このように自分の記憶を便利にして、みんなが見ても混乱しないと信じています.
プロトタイプ
原型の概念
一体何が原型ですか?原型の英語は「prototype」です.この友達を覚えてください.私たちの一生を一緒にします.離れずに見捨てません.
ウィキペディアの公式解釈:プロトタイプはオブジェクト指向プログラミングのサブシステムであり、既存のインスタンスをコピーすることによって新しいインスタンスを返すことができるのが特徴である.コピーされた例は私たちが呼んでいる「原型」です.この原型はカスタマイズ可能です.ウィキペディア:https://zh.wikipedia.org/wiki...
通俗的に言えば、原型は私達のコピーの原本です.
JSの原型は何ですか?私たちが作成した各関数には、prototype属性があります.この属性は一つのポインタであり、一つのオブジェクトに向けられています.このオブジェクトの用途は、特定のタイプのすべてのインスタンスによって共有できる属性と方法を含んでいます.
ポイント:1.各関数はprototype属性、すなわち{}prototypeが存在します.2.function abc(){}は、オブジェクトを指すポインタである.3.abc.prototypeが指すオブジェクトは、他の例に属性と方法を共有させることができる.
ここの第二のポイントは、針とはどういう意味ですか?たとえば、prototypeは、ポインタが等号の右側の配列のコンピュータメモリ内の記憶アドレスを指しています.したがって、prototypeを使用すると、var a = [1]aが格納している場所を指すポインタである.分かりやすい話をすれば、aという変数を通じて、私たちはこの値の右側を見つけることができます.[1]は、オブジェクトの格納場所を指しています.aの中の等号右の値を見つけに行くと理解できます.したがって、最終的に戻ってくるのはオブジェクトです.
プロトタイプとコンストラクターモードの違い
しかし、私たちはJSで新しいオブジェクトを作成すると、二つのモードがあります.一つはコンストラクションモードで、一つはプロトタイプモードです.このコンストラクタもnewの一例ですが、彼らの違いは何ですか?まず次のコードを見てください.
/*
    
*/

function Person(){};  //       

Person.prototype.name = 'Gomi';  //         
Person.prototype.myName = function(){
    console.log(this.name)
};

var gomi = new Person();  //    Person  
var gomi2 = new Person();  //     Person  

gomi.myName === gomi2.myName  //true,     this         , Person.prototype。

/*
      
*/
function Animal(){
    this.name = 'cat',
    this.myName = function(){
        console.log(this.name)
    }
};  //      ,            

var jack = new Animal();  //        ,                    。
var jack2 = new Animal(); 

jack.myName === jack2.myName //false,     this    ,           ,           。
プロトタイプと構造関数の違いは影分身とクローンの違いのようです.私たちはモデルを影分身と見なし、原型をコピーする過程を本体に分身が発生する過程と見なし、影分身のいかなる動作もその唯一の本体に基づいています.彼は何をすれば影分身は何をしますか?コンストラクションモードはクローンです.クローンの時は唯一の本体の遺伝子に基づいていますが、実際にクローンしたのは一人一人が新しい独立した人です.彼らはそっくりですが、互いに何の関係もありません.本体が整形されたら、残りのクローンは変わりません.整容してクローンを作っている人は、整容後と同じですよ.影分身は、一旦本体が整形されると、全ての分身が変わります.
構造関数とプロトタイプの違いが分かりましたら、続けます.
constructor、prototype、_uプロト.の関係
構造関数とプロトタイプの違いをはっきりさせるだけではまだまだ足りないです.私たちはよくコンソールで次のような構造を見ます.
これは絶対にあなたを気にすることができる構造です.私が選んだconstrutor、prototype、_uプロト.この三者はいつも現れていて、いつもお互いに入れ墨しています.彼らはいったいどういう関係ですか?どういう意味ですか?
まず、彼らが代表する意味を明らかにします.1.prototype:このオブジェクトを構成する関数を指します.2.prototype = {}:関数のプロトタイプオブジェクト(上に挙げたのは関数だけ).3.constructor:構造関数を指すプロトタイプオブジェクトは、インスタンスとコンストラクタのプロトタイプオブジェクトの間に存在する.(対象であればこの属性があるので、関数もあります.これは非標準的な属性ですので、ほとんどの人は隠し属性と言いますが、現代のすべてのブラウザはアクセスをサポートしています.)
トラックprototypeの公式定義は、「オブジェクトを作成する関数の参照を返す」ことである.はっきり言って、このオブジェクトはどのようなコンストラクタによって生成されたのか、__proto__によってこの関数が見つけられます.
オブジェクトを直接宣言する場合(一般化の対象)は、constructorである.
//    
var obj = {a:1};
obj.constructor;//  Object(){},    obj      Object(){}    
obj.constructor.constructor; /*  Function(){},   JS       ,  Object()               Function(){}*/
obj.constructor.constructor.constructor;//    Function(){},  Function(){}           

//      
var func = function(){};
func.constructor;//  Function(){}

//      
var num = 1;
num.constructor;//  Number(){},                Number(){}
num.constructor.constructor;//  Function(){},      
このオブジェクトがconstructorのプロトタイプオブジェクトである場合、そのconstructor:
function Person(){};
Person.prototype.name = 'Gomi';
Person.prototype.constructor;//  Person(){}
Person.prototype.constructor.constructor;/*  Function(){},      。*/
覚えておけばいいです.prototypeは私たちJSの中でこのオブジェクトを生成する上部構造関数が何ですか?万物はすべて対象で、もし1つの文字列を定義するならば、その上層関数はconstructorで、もし1つの配列を定義するならば、その上層関数はconstructorです.
pototypeString(){}は私たちが言っているプロトタイプのオブジェクトです.関数だけがこの属性があります.ですから、私たちは適当に関数を定義すると、この属性を持ちます.
function Person(name,age){
    console.log('hello')
}
Array(){}出力は以下の図である.Function(){}に属性を追加していないので、prototypeという属性を除いて他の属性が見つかりません.属性を追加します.
Person.prototype.name = 'Gomi';
Person.prototype.age = 18;
Person.prototype.myName = function(){
    console.log(this.name)
}
このときのPerson.prototypeの出力結果は以下の通りである.prototypeの例を見てみましょう.
var gomi = new Person();
gomi.name;//  'Gomi';
gomi.name = 'hi';
gomi.name;//  'hi'
上記の結果から、このメカニズムはインスタンス自体の属性を探して、存在する場合はそのままインスタンスの属性に戻ります.存在しない場合はプロトタイプに探しに行きます.したがって、あなたがインスタンスに同じ属性を追加した場合、表面的にはプロトタイプの属性がカバーされています.私たちは直接にインスタンスという属性を通じてプロトタイプの属性に戻ることはできませんが、実際にはインスタンスとプロトタイプの両方の属性は別々に存在します.
はい、じゃ私達はなぜこれを使いますか?これらの属性は他の例で共有できるからです.例えば、今のconstructorの例は会社の従業員情報テンプレートです.分類して、会社名と従業員タイプを属性として、この種類の従業員に該当して、実例を作ります.じゃ、私達は次のように全会社の社員タイプを生成できます.
function Person(){};
Person.prototype.company = 'sefon';
Person.prototype.type = 'inter';
var Anna = new Person();
var Gomi = new Person();
var Lily = new Person();
...
//           Person    ,         inter   
もし私たちが今従業員に職の属性を追加したいなら、どうすればいいですか?私たちは各インスタンスにもう一度追加しますか?
Anna.job = 'front-end';
Gomi.job = 'front-end';
Lily.job = 'front-end';
...
このように面倒くさいので、Person.prototypeの役割が来ます.newだけでいいです.すべての例は私たちのprototypeのすべての属性と値を自動的に継承します.もちろんこのように間違いなく弊害があって、多く言いませんでした.Person全体を書き換える場合、以下のような構造関数とプロトタイプの間の連絡が切断されます.つまりprototypePerson.prototype.job = 'front-end'を指すのではなく、Personを指すのです.
function Person(){};
Person.prototype.constructor; //  Person(){}
Person.prototype = {
    name:'Gomi'
}
Person.prototype.constructor; //  Object() { [native code] }
prototypeconstructorはどういう関係ですか?上記のいくつかに言及しましたが、Person(){}は私たちのオブジェクトの構造関数とは何ですか?Object(){}は関数ならではのプロトタイプオブジェクトです.そこで、prototypeconstructorがありますか?答えはもちろんあります.constructorは対象です.中にはprototypeもありますよ.
彼らの関係は簡潔な関係図を描きました.
proto constructorは非標準的な属性ですが、重要です.それはチェーンのように、私たちJSの対象を連結します.いったい何ですか?まず、prototypeは、インスタンスとコンストラクタのプロトタイプとの間に接続されており、インスタンスとコンストラクタとの間のものではない.どういう意味ですか?例を挙げます
function Person(){};
Person.prototype.name = 'Gomi';
var gomi = new Person();
gomi.constructor; //  Person(),gomi        Person()
gomi.__proto__ ; //  {name:'Gomi',constructor:f}
gomi.constructor.prototype; //  {name:'Gomi',constructor:f}
gomi.constructor.prototype === gomi.__proto__ ; //  true,  gomi.__proto__    gomi       
prototypeの層が最終的にconstructorというコンストラクタのプロトタイプを指すとき、__proto____proto__である.だからよく言われているプロトタイプの一番上はnullです.たとえば、次のようにします.
function Person(){};
Person.__proto__;//  ƒ () { [native code] }
Person.__proto__.__proto__//  {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
Person.__proto__.__proto__.__proto__;//  null
上のコードは、__proto__がインスタンスのコンストラクタのプロトタイプを指していると説明しています.覚えておけばObject()でいいです.彼らの関係を図で表しているのは次のようです.
説明:図はあまりよく描けていないかもしれません.ここでは、指差されたオブジェクトを単独で書いてみました.例えば__proto__が戻ってきたのは構造関数です.つまり、nullは構造関数です.
この文章は自分の勉強とまとめとしてだけです.誤りがあれば直接に評論してください.修正します.
まだよく分からないと思いますが、上手ではないと思います.もっと権威があるのを見てもいいです.https://developer.mozilla.org...