• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. javascript 原型鏈維護和繼承詳解

        時間:2024-10-25 19:00:49 JavaScript 我要投稿
        • 相關推薦

        關于javascript 原型鏈維護和繼承詳解

          一.兩個原型

          很多人都知道javascript是原型繼承,每個構造函數都有一個prototype成員,通過它就可以把javascript的繼承演義的美輪美奐了.

          其實啊,光靠這一個屬性是無法完成javascript的繼承.

          我們在代碼中使用的prototype完成繼承在這里就不多說了.大家可以查一下資料.

          另外一個看不見的prototype成員.

          每一個實例都有有一條指向原型的prototype屬性,這個屬性是無法被訪問到的,當然也就無法被修改了,因為這是維護javascript繼承的基礎.

          復制代碼 代碼如下:

          //構造器聲明

          function Guoyansi(){ }

          function GuoyansiEx(){}

          //原型繼承

          GuoyansiEx.prototype=new Guoyansi();

          //創建對象

          var g1=new GuoyansiEx();

          var g2=new GuoyansiEx();

          上面的代碼中的對象可以用下面的圖來說明

          二.原型的維護

          一個構造器產生的實例,其constructor屬性總是指向該構造器.我們暫且認為該話是對的.

          復制代碼 代碼如下:

          function Guoyansi(){ }

          var obj1=new Guoyansi();

          console.log(obj1.constructor===Guoyansi);//true

          其實構造器本身是沒有constructor這個屬性的,那么這個屬性是來自哪呢?

          答案是:來自原型.

          因此得出下面的結論

          復制代碼 代碼如下:obj1.constructor===Guoyansi.prototype.constructor===Guoyansi

          既然我們可以通過constructor來尋找構造器.因此我們就可以進一步完善上面的圖了.

          復制代碼 代碼如下:

          function GuoyansiEx(){}

          GuoyansiEx.prototype=new Guoyansi();

          console.log(GuoyansiEx.constructor===GuoyansiEx)//false

          根據上圖,上面的結果應該是true,但為什么是false呢?

          現在做個分析.

          GuoyansiEx的原型被Guoyansi的實例重寫了,那么GuoyansiEx的原型中的constructor自然也是來自Guoyansi的實例.

          而Guoyansi實例中的constructor又是來自Guoyansi.prototype.而Guoyansi.prototype沒有被重寫,

          所以Guoyansi.prototype的constructor指向Guoyansi(構造函數);

          根據以上分析得出下面的結論

          復制代碼 代碼如下:GuoyansiEx.constructor===Guoyansi.constructor===Guoyansi;

          如果在開發過程中對于Constructor的指向要求非常精確的話,可以做如下處理.

          復制代碼 代碼如下:

          /**方法一:**/

          function Guoyansi(){}

          function GuoyansiEx(){}

          GuoyansiEx.prototype=new Guoyansi();

          GuoyansiEx.prototype.constructor=GuoyansiEx;//重置constructor指向.

          復制代碼 代碼如下:

          /**

          方法二

          **/

          function Guoyansi(){}

          function GuoyansiEx(){

          this.constructor=arguments.callee;

          }

          GuoyansiEx.prototype=new Guoyansi();

          復制代碼 代碼如下:

          /**

          方法三

          **/

          function Guoyansi(){}

          function GuoyansiEx(){

          this.constructor=GuoyansiEx;

          }

          GuoyansiEx.prototype=new Guoyansi();

          三.看不見的原型有什么用呢?

          看得見的原型鏈我們可以對他操作來完成我們的繼承,那么這個看不見的原型鏈我們既看不見,又無法操作.要它有何用.

          面向對象中繼承有一個特性:相似性.子類與父類具有相似性.因此在子類中你是無法用刪除從父類繼承而來的成員.也就是說子類必須具有父類的特性.

          為了維護這個特性,javascript在對象的內部產生了一條我們看不見的原型屬性,并且不允許用戶訪問.這樣,用戶可以處于任何目的來修改constructor,

          而不會破壞子類擁有父類的特性.

          簡而言之:內部原型是javascript的原型繼承機制所需要的,而外部原型是用戶實現繼承所需要的.

          四.火狐引擎SpiderMonkey中的__proto__

          還是這段代碼.

          復制代碼 代碼如下:

          function Guoyansi(){}

          Guoyansi.prototype.age=24;

          function GuoyansiEx(){}

          var obj1=new Guoyansi();

          GuoyansiEx.prototype=obj1;

          GuoyansiEx.prototype.constructor=GuoyansiEx;//重置constructor指向.

          var obj2=new GuoyansiEx();

          我現在想要從obj開始向上訪問父類Guoyansi的prototype的屬性的age.

          思路是這樣的.

          第一步:obj2====>obj2.constructor.prototype

          第二部:obj2.constructor.prototype===>GuoyansiEx.prototype;

          第三部:GuoyansiEx.prototype===>obj1;

          第四部:obj1.constructor====>Guoyansi

          第五部:Guoyansi.prototype.age

          寫成這這樣:console.log(obj2.constructor.prototype.constructor.prototype.age)//24;

          最終的結果是24.

          最終的結果是24.可以正常執行,但是在好多書上說constructor修改后,級無法在找到父類中的原型了.不知道是怎么回事.

          在火狐中提夠了一種更加簡潔的屬性._proto_

          SpiderMonkey中默認在任何創建的對象上添加了一個名為_proto_的屬性,該屬性指向構造器所用的原型.

          其實就是我們上面提到的不可見的原型鏈,只不過是在這個地方變相的公開而已.

          可以這樣訪問到age

          console.log(obj2.__proto__.__proto__.age);//24

          這樣的確是成功的訪問到了父類的原型屬性,但是這個屬性只適用于火狐,在其他瀏覽器中是會出錯的.

          在E5中對Object做出了擴展Object.getPrototypeOf(),可以訪問到所有父類的原型了.

          復制代碼 代碼如下:

          function Guoyansi(){}

          Guoyansi.prototype.age=24;

          function GuoyansiEx(){}

          var obj1=new Guoyansi();

          GuoyansiEx.prototype=obj1;

          GuoyansiEx.prototype.constructor=GuoyansiEx;//重置constructor指向.

          var obj2=new GuoyansiEx();

          var proto=Object.getPrototypeOf(obj2);

          while(proto){

          console.log(proto.constructor);

          proto=Object.getPrototypeOf(proto);

          }

          console.log("object的原型"+proto);

          結果是:GuoyansiEx

          Guoyansi

          Object

          object的原型null

          個人覺得這些應該算是javascript面向對象的精髓之一了.小伙伴們自己參考下,根據需求使用到自己的項目中去吧

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

        【javascript 原型鏈維護和繼承詳解】相關文章:

        理解JavaScript原型鏈教程09-02

        Javascript中arguments對象的詳解和使用方法08-20

        JavaScript中push(),join() 函數實例詳解09-05

        詳解SEO外鏈本質10-24

        詳解JavaScript中的splice()使用方法08-20

        JavaScript類定義原型方法的兩種實現的區別07-11

        Javascript函數的定義和用法分析08-15

        網站外鏈與網站優化的之間關系詳解10-24

        網站內鏈和外鏈的定義及區別09-28

        如何提高網站內鏈和外鏈的收錄?08-09

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 一区二区三区精品国产日韩免费 | 日韩无砖专区一中文字目码 | 亚洲中文字幕久久网 | 亚洲一级一区二区三 | 在线日韩欧美国产二区 | 亚洲一品道在线观看 |

            關于javascript 原型鏈維護和繼承詳解

              一.兩個原型

              很多人都知道javascript是原型繼承,每個構造函數都有一個prototype成員,通過它就可以把javascript的繼承演義的美輪美奐了.

              其實啊,光靠這一個屬性是無法完成javascript的繼承.

              我們在代碼中使用的prototype完成繼承在這里就不多說了.大家可以查一下資料.

              另外一個看不見的prototype成員.

              每一個實例都有有一條指向原型的prototype屬性,這個屬性是無法被訪問到的,當然也就無法被修改了,因為這是維護javascript繼承的基礎.

              復制代碼 代碼如下:

              //構造器聲明

              function Guoyansi(){ }

              function GuoyansiEx(){}

              //原型繼承

              GuoyansiEx.prototype=new Guoyansi();

              //創建對象

              var g1=new GuoyansiEx();

              var g2=new GuoyansiEx();

              上面的代碼中的對象可以用下面的圖來說明

              二.原型的維護

              一個構造器產生的實例,其constructor屬性總是指向該構造器.我們暫且認為該話是對的.

              復制代碼 代碼如下:

              function Guoyansi(){ }

              var obj1=new Guoyansi();

              console.log(obj1.constructor===Guoyansi);//true

              其實構造器本身是沒有constructor這個屬性的,那么這個屬性是來自哪呢?

              答案是:來自原型.

              因此得出下面的結論

              復制代碼 代碼如下:obj1.constructor===Guoyansi.prototype.constructor===Guoyansi

              既然我們可以通過constructor來尋找構造器.因此我們就可以進一步完善上面的圖了.

              復制代碼 代碼如下:

              function GuoyansiEx(){}

              GuoyansiEx.prototype=new Guoyansi();

              console.log(GuoyansiEx.constructor===GuoyansiEx)//false

              根據上圖,上面的結果應該是true,但為什么是false呢?

              現在做個分析.

              GuoyansiEx的原型被Guoyansi的實例重寫了,那么GuoyansiEx的原型中的constructor自然也是來自Guoyansi的實例.

              而Guoyansi實例中的constructor又是來自Guoyansi.prototype.而Guoyansi.prototype沒有被重寫,

              所以Guoyansi.prototype的constructor指向Guoyansi(構造函數);

              根據以上分析得出下面的結論

              復制代碼 代碼如下:GuoyansiEx.constructor===Guoyansi.constructor===Guoyansi;

              如果在開發過程中對于Constructor的指向要求非常精確的話,可以做如下處理.

              復制代碼 代碼如下:

              /**方法一:**/

              function Guoyansi(){}

              function GuoyansiEx(){}

              GuoyansiEx.prototype=new Guoyansi();

              GuoyansiEx.prototype.constructor=GuoyansiEx;//重置constructor指向.

              復制代碼 代碼如下:

              /**

              方法二

              **/

              function Guoyansi(){}

              function GuoyansiEx(){

              this.constructor=arguments.callee;

              }

              GuoyansiEx.prototype=new Guoyansi();

              復制代碼 代碼如下:

              /**

              方法三

              **/

              function Guoyansi(){}

              function GuoyansiEx(){

              this.constructor=GuoyansiEx;

              }

              GuoyansiEx.prototype=new Guoyansi();

              三.看不見的原型有什么用呢?

              看得見的原型鏈我們可以對他操作來完成我們的繼承,那么這個看不見的原型鏈我們既看不見,又無法操作.要它有何用.

              面向對象中繼承有一個特性:相似性.子類與父類具有相似性.因此在子類中你是無法用刪除從父類繼承而來的成員.也就是說子類必須具有父類的特性.

              為了維護這個特性,javascript在對象的內部產生了一條我們看不見的原型屬性,并且不允許用戶訪問.這樣,用戶可以處于任何目的來修改constructor,

              而不會破壞子類擁有父類的特性.

              簡而言之:內部原型是javascript的原型繼承機制所需要的,而外部原型是用戶實現繼承所需要的.

              四.火狐引擎SpiderMonkey中的__proto__

              還是這段代碼.

              復制代碼 代碼如下:

              function Guoyansi(){}

              Guoyansi.prototype.age=24;

              function GuoyansiEx(){}

              var obj1=new Guoyansi();

              GuoyansiEx.prototype=obj1;

              GuoyansiEx.prototype.constructor=GuoyansiEx;//重置constructor指向.

              var obj2=new GuoyansiEx();

              我現在想要從obj開始向上訪問父類Guoyansi的prototype的屬性的age.

              思路是這樣的.

              第一步:obj2====>obj2.constructor.prototype

              第二部:obj2.constructor.prototype===>GuoyansiEx.prototype;

              第三部:GuoyansiEx.prototype===>obj1;

              第四部:obj1.constructor====>Guoyansi

              第五部:Guoyansi.prototype.age

              寫成這這樣:console.log(obj2.constructor.prototype.constructor.prototype.age)//24;

              最終的結果是24.

              最終的結果是24.可以正常執行,但是在好多書上說constructor修改后,級無法在找到父類中的原型了.不知道是怎么回事.

              在火狐中提夠了一種更加簡潔的屬性._proto_

              SpiderMonkey中默認在任何創建的對象上添加了一個名為_proto_的屬性,該屬性指向構造器所用的原型.

              其實就是我們上面提到的不可見的原型鏈,只不過是在這個地方變相的公開而已.

              可以這樣訪問到age

              console.log(obj2.__proto__.__proto__.age);//24

              這樣的確是成功的訪問到了父類的原型屬性,但是這個屬性只適用于火狐,在其他瀏覽器中是會出錯的.

              在E5中對Object做出了擴展Object.getPrototypeOf(),可以訪問到所有父類的原型了.

              復制代碼 代碼如下:

              function Guoyansi(){}

              Guoyansi.prototype.age=24;

              function GuoyansiEx(){}

              var obj1=new Guoyansi();

              GuoyansiEx.prototype=obj1;

              GuoyansiEx.prototype.constructor=GuoyansiEx;//重置constructor指向.

              var obj2=new GuoyansiEx();

              var proto=Object.getPrototypeOf(obj2);

              while(proto){

              console.log(proto.constructor);

              proto=Object.getPrototypeOf(proto);

              }

              console.log("object的原型"+proto);

              結果是:GuoyansiEx

              Guoyansi

              Object

              object的原型null

              個人覺得這些應該算是javascript面向對象的精髓之一了.小伙伴們自己參考下,根據需求使用到自己的項目中去吧