js 原型鏈繼承__proto__、prototype簡析

yesye發表於2021-09-09

js中的繼承關鍵是靠__proto__屬性實現的
prototype屬性的職責是將原型鏈中的資料放入__proto__中的中介,即我們在new 一個物件的時候

js中有兩種物件,即函式物件和普通物件
  • 函式物件: 凡是透過new Function()建立的都是函式物件
    函式物件屬性包含__proto__和prototype兩個屬性;而普通物件有__proto__沒有prototype屬性,
    像 Number;Object;Array都是函式物件

//例如 var a = function(){};  function a(){}; var a = new Function(); var a = Function();
  • 普通物件: 不是透過new Function()建立的物件

//例如
 var a = 1 即(a = new Number(1)); var a = 'hello'即(a = new String(1));var a = []即(a = new Array());
  • __proto__
    主要用來回溯物件,即用來繼承的,即當執行a.b的時候,如果當前物件沒有定義b屬性,則會透過a.__proto__到父物件中查詢,以此類推

  • prototype
    *其值是函式建立的時候建立了一個它的例項物件,並賦值給prototype,其作用是將值傳遞給例項物件的__proto__,以實現繼承

  • 例項程式碼  Function
    主要演示函式物件Function的__proto__屬性以及prototype屬性的值

   console.log('--------------------------------函式物件Function--------------------------------------'); //函式物件Function   Function.prototype === Function.__proto__  (true)
 //此例比如 var temp = new Function();Function.prototype = temp;//所以Function.prototype 為function
 console.log('Function.prototype:',Function.prototype); console.log('Function.__proto__:',Function.__proto__); //原始物件Object
 console.log('Function.prototype.__proto__:',Function.prototype.__proto__); console.log('Function.__proto__.__proto__:',Function.__proto__.__proto__); //一切的起點null 所有物件透過__proto__回溯都會找到null
 console.log('Function.prototype.__proto__.__proto__:',Function.prototype.__proto__.__proto__); console.log('Function.__proto__.__proto__.__proto__:',Function.__proto__.__proto__.__proto__); //會抱錯,null是起點 null沒有__proto__屬性 不能在回溯console.log('Function.prototype.__proto__.__proto__.__proto__:',Function.__proto__.__proto__.__proto__.__proto__);console.log('Function.__proto__.__proto__.__proto__.__proto__:',Function.__proto__.__proto__.__proto__.__proto__);
  • chrome下輸出


    圖片描述

    1.png

  • 例項程式碼  Number
    主要演示函式物件Number的__proto__屬性以及prototype屬性的值

   console.log('--------------------------------函式物件Number--------------------------------------'); //函式物件Number  其實可以理解為var Number = new Function();
 //原型物件prototype的值實際是函式建立的時候建立了一個它的例項物件,並賦值給prototype//此例比如  var temp = new Number();Number.prototype = temp;Number.prototype 為Number的例項物件,是普通物件,繼承自Object//所以typeof Number.prototype 為 Object//Number為Function的例項物件,而Function.__proto__為function ,//所以typeof Number.__proto__ 為 functionconsole.log('Number.prototype:',Number.prototype);console.log('Number.__proto__:',Number.__proto__);console.log('typeof Number.prototype:',typeof Number.prototype);console.log('typeof Number.__proto__:',typeof Number.__proto__);//原始物件Objectconsole.log('Number.prototype.__proto__:',Number.prototype.__proto__);console.log('Number.__proto__.__proto__:',Number.__proto__.__proto__);//原始物件 無中生有的無 即null,console.log('Number.prototype.__proto__.__proto__:',Number.prototype.__proto__.__proto__);console.log('Number.__proto__.__proto__.__proto__:',Number.__proto__.__proto__.__proto__);//會抱錯,因為null沒有__proto__屬性console.log('Number.prototype.__proto__.__proto__.__proto__:',Number.__proto__.__proto__.__proto__.__proto__);console.log('Number.__proto__.__proto__.__proto__.__proto__:',Number.__proto__.__proto__.__proto__.__proto__);
  • chrome下輸出


    圖片描述

    2.png

  • 例項程式碼  Object
    主要演示函式物件Object的__proto__屬性以及prototype屬性的值

console.log('--------------------------------函式物件Object--------------------------------------');console.log('Object.prototype:',Object.prototype);console.log('Object.__proto__:',Object.__proto__);console.log('typeof Object.prototype:',typeof Object.prototype);console.log('typeof Object.__proto__:',typeof Object.__proto__);//原始物件 無中生有的無 即null,console.log('Object.prototype.__proto__:',Object.prototype.__proto__);//Objectconsole.log('Object.__proto__.__proto__:',Object.__proto__.__proto__);//nullconsole.log('Object.__proto__.__proto__.__proto__:',Object.__proto__.__proto__.__proto__); 
//抱錯//console.log('Object.prototype.__proto__.__proto__:',Object.prototype.__proto__.__proto__);
  • chrome下輸出


    圖片描述

    3.png

  • 例項程式碼
    主要演示普通物件的__proto__屬性以及prototype屬性的值

console.log('--------------------------------普通物件--------------------------------------'); //例如 var a = 1 即(a = new Number(1)); var a = 'hello'即(a = new String(1));var a = []即(a = new Array());
   function obj(){    this.a = 1;this.b = 2; }
    obj.prototype.pMethod=function(){    console.log('ddd');
   }   var c = new obj();//普通物件c 沒有prototype屬性,所以typeof c.prototype 為 Object//c為Function的例項物件,而Function.__proto__為function //所以typeof c.__proto__ 為 functionconsole.log('c.prototype:',c.prototype);  //undefined//我們再來看看__proto__的定義:他的值是建立例項物件的時候對應的函式物件的原型物件//即obj.prototype = new obj();//obj.prototype.pMethod=function(){console.log('ddd');}//c.__proto__ = obj.prototype;//此時__proto__中有obj例項物件以及pMethod函式、__prototype__ 屬性
   console.log('c.__proto__:',c.__proto__);//如果我們這樣定義原型鏈函式
   obj.prototype = {    pMethod:function(){     console.log('ddd');
    }
   }   var c = new obj();   //__proto__的定義:他的值是建立例項物件的時候對應的函式物件的原型物件
   //即obj.prototype = new obj();
   //obj.prototype= {pMethod:function(){console.log('ddd');}}
   //c.__proto__ = obj.prototype
   //此時__proto__中有pMethod函式、__prototype__ 屬性
   console.log('c.__proto__:',c.__proto__);   //原始物件Object
   console.log('c.__proto__.__proto__:',c.__proto__.__proto__);   //原始物件 無中生有的無 即null,
 console.log('c.__proto__.__proto__.__proto__:',c.__proto__.__proto__.__proto__);//會抱錯,因為null沒有__proto__屬性 //console.log('c.prototype.__proto__.__proto__.__proto__:',c.__proto__.__proto__.__proto__.__proto__);
  • chrome下輸出


    圖片描述

    4.png

總結

一個物件的proto記錄著自己的原型鏈,決定了自身的資料型別,改變proto就等於改變物件的資料型別。
函式的prototype不屬於自身的原型鏈,其值是建立函式物件的例項,它是子類建立的核心,決定了子類的資料型別,是連線子類原型鏈的橋樑。
在原型物件上定義方法和屬性的目的是為了被子類繼承和使用



作者:zhifeichuan
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2041/viewspace-2802556/,如需轉載,請註明出處,否則將追究法律責任。

相關文章