一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看

javascript 原型鏈維護和繼承詳解

時(shí)間:2024-10-25 19:00:49 JavaScript 我要投稿
  • 相關(guān)推薦

關(guān)于javascript 原型鏈維護和繼承詳解

  一.兩個(gè)原型

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

  其實(shí)啊,光靠這一個(gè)屬性是無(wú)法完成javascript的繼承.

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

  另外一個(gè)看不見(jiàn)的prototype成員.

  每一個(gè)實(shí)例都有有一條指向原型的prototype屬性,這個(gè)屬性是無(wú)法被訪(fǎng)問(wèn)到的,當然也就無(wú)法被修改了,因為這是維護javascript繼承的基礎.

  復制代碼 代碼如下:

  //構造器聲明

  function Guoyansi(){ }

  function GuoyansiEx(){}

  //原型繼承

  GuoyansiEx.prototype=new Guoyansi();

  //創(chuàng )建對象

  var g1=new GuoyansiEx();

  var g2=new GuoyansiEx();

  上面的代碼中的對象可以用下面的圖來(lái)說(shuō)明

  二.原型的維護

  一個(gè)構造器產(chǎn)生的實(shí)例,其constructor屬性總是指向該構造器.我們暫且認為該話(huà)是對的.

  復制代碼 代碼如下:

  function Guoyansi(){ }

  var obj1=new Guoyansi();

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

  其實(shí)構造器本身是沒(méi)有constructor這個(gè)屬性的,那么這個(gè)屬性是來(lái)自哪呢?

  答案是:來(lái)自原型.

  因此得出下面的結論

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

  既然我們可以通過(guò)constructor來(lái)尋找構造器.因此我們就可以進(jìn)一步完善上面的圖了.

  復制代碼 代碼如下:

  function GuoyansiEx(){}

  GuoyansiEx.prototype=new Guoyansi();

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

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

  現在做個(gè)分析.

  GuoyansiEx的原型被Guoyansi的實(shí)例重寫(xiě)了,那么GuoyansiEx的原型中的constructor自然也是來(lái)自Guoyansi的實(shí)例.

  而Guoyansi實(shí)例中的constructor又是來(lái)自Guoyansi.prototype.而Guoyansi.prototype沒(méi)有被重寫(xiě),

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

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

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

  如果在開(kāi)發(fā)過(guò)程中對于Constructor的指向要求非常精確的話(huà),可以做如下處理.

  復制代碼 代碼如下:

  /**方法一:**/

  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();

  三.看不見(jiàn)的原型有什么用呢?

  看得見(jiàn)的原型鏈我們可以對他操作來(lái)完成我們的繼承,那么這個(gè)看不見(jiàn)的原型鏈我們既看不見(jiàn),又無(wú)法操作.要它有何用.

  面向對象中繼承有一個(gè)特性:相似性.子類(lèi)與父類(lèi)具有相似性.因此在子類(lèi)中你是無(wú)法用刪除從父類(lèi)繼承而來(lái)的成員.也就是說(shuō)子類(lèi)必須具有父類(lèi)的特性.

  為了維護這個(gè)特性,javascript在對象的內部產(chǎn)生了一條我們看不見(jiàn)的原型屬性,并且不允許用戶(hù)訪(fǎng)問(wèn).這樣,用戶(hù)可以處于任何目的來(lái)修改constructor,

  而不會(huì )破壞子類(lèi)擁有父類(lèi)的特性.

  簡(jiǎn)而言之:內部原型是javascript的原型繼承機制所需要的,而外部原型是用戶(hù)實(shí)現繼承所需要的.

  四.火狐引擎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開(kāi)始向上訪(fǎng)問(wèn)父類(lèi)Guoyansi的prototype的屬性的age.

  思路是這樣的.

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

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

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

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

  第五部:Guoyansi.prototype.age

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

  最終的結果是24.

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

  在火狐中提夠了一種更加簡(jiǎn)潔的屬性._proto_

  SpiderMonkey中默認在任何創(chuàng )建的對象上添加了一個(gè)名為_(kāi)proto_的屬性,該屬性指向構造器所用的原型.

  其實(shí)就是我們上面提到的不可見(jiàn)的原型鏈,只不過(guò)是在這個(gè)地方變相的公開(kāi)而已.

  可以這樣訪(fǎng)問(wèn)到age

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

  這樣的確是成功的訪(fǎng)問(wèn)到了父類(lèi)的原型屬性,但是這個(gè)屬性只適用于火狐,在其他瀏覽器中是會(huì )出錯的.

  在E5中對Object做出了擴展Object.getPrototypeOf(),可以訪(fǎng)問(wèn)到所有父類(lèi)的原型了.

  復制代碼 代碼如下:

  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

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

【javascript 原型鏈維護和繼承詳解】相關(guān)文章:

理解JavaScript原型鏈教程09-02

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

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

詳解SEO外鏈本質(zhì)10-24

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

JavaScript類(lèi)定義原型方法的兩種實(shí)現的區別07-11

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

網(wǎng)站外鏈與網(wǎng)站優(yōu)化的之間關(guān)系詳解10-24

網(wǎng)站內鏈和外鏈的定義及區別09-28

如何提高網(wǎng)站內鏈和外鏈的收錄?08-09

一级日韩免费大片,亚洲一区二区三区高清,性欧美乱妇高清come,久久婷婷国产麻豆91天堂,亚洲av无码a片在线观看