亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JS Pro-深入面向對象的程序設計之繼承的詳解

2019-11-20 22:44:27
字體:
來源:轉載
供稿:網友

原型鏈(prototype chaining):

利用原型來繼承屬性和方法?;仡櫼幌聵嬙旌瘮担╟onstructor),原型對象(prototype)和實例(instance)的關系。每一個構造函數都有一個prototype屬性,該屬性指向一個prototype對象;prototype對象也有constructor屬性,指向該函數;而實例也有一個內部指針(__proto__)指向這個prototype對象。如果這個prototype對象是另外一個對象的實例會是怎樣的呢?這樣該prototype對象就包含一個指向另一個類型的指針,相應地,另一個原型中也包含著一個指向另一個構造函數的指針。

JS的繼承很簡單,就是把子類的prototype設為父類的一個(實例化)對象

復制代碼 代碼如下:

function SuperType(){
    this.property = true;
}

SuperType.prototype.getSuperValue = function(){
    return this.property;
};

function SubType(){
    this.subproperty = false;
}

//inherit from SuperType
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function (){
    return this.subproperty;
};

var instance = new SubType();
alert(instance.getSuperValue());   //true

最終的結果:instance的__proto__指向SubType.prototype對象,而SubType.prototype對象的__proto__屬性又指向SuperType.prototype對象。getSuperValue()是一個方法,所以仍然存在于原型中,而property是一個實例屬性,所以現在存在于SubType.prototype這個實例中。  instance.constructor現在指向的是SuperType,這是由于SubType.prototype指向SuperType.prototype,而SuperType.prototype的constructor屬性指向SuperType函數,所以instance.constructor指向SuperType。

默認情況下,所有引用類型都繼承Object。這是因為所有函數的原型對象,默認都是Object的一個實例,所以內部prototype(__proto__)指向Object.Prototype。

原型和實例的關系:可以使用2種方法來確定原型與實例之間的關系。
- instancef操作符:使用該操作符來測試實例與原型鏈中出現過的構造函數,都會返回true

復制代碼 代碼如下:

alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true

- isPrototypeOf()方法:只要是原型鏈中出現過的原型,都可以說是該原型鏈所派生的實例的原型。
復制代碼 代碼如下:

alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true

給子類添加方法的注意點:我們有的時候會給子類添加方法,或者是重寫父類的某些方法。這個時候就要注意,這些方法必須在繼承后再定義。以下的例子里,SubType在繼承SuperType后,我們給它添加了新的方法getSubValue(),而且重寫了getSuperValue()方法。對于后者,只有SubType的實例才會使用重寫的方法,SuperType的實例還是會使用原有的getSuperValue()方法。
復制代碼 代碼如下:

function SuperType(){
  this.property = true;
}
SuperType.prototype.getSuperValue = function(){
  return this.property;
};
function SubType(){
  t his.subproperty = false;
}
//inherit from SuperType
SubType.prototype = new SuperType();
//new method
SubType.prototype.getSubValue = function (){
  return this.subproperty;
};
//override existing method
SubType.prototype.getSuperValue = function (){
  return false;
};
var instance = new SubType();
alert(instance.getSuperValue()); //false

另外一個需要注意的是,通過原型鏈實現繼承時,不能使用對象字面量創建原型方法,因為這樣會重寫原型鏈。如下面的代碼,在SubType繼承SuperType以后,使用對象字面量給原型添加方法,但這樣做,會重寫SubType原型,重寫后的SubType.prototype包含的是一個Object的實例,從而也切斷了與SuperType的關系。
復制代碼 代碼如下:

function SuperType(){
  this.property = true;
}
SuperType.prototype.getSuperValue = function(){
  return this.property;
};
function SubType(){
  this.subproperty = false;
}
//inherit from SuperType
SubType.prototype = new SuperType();
//try to add new methods - this nullifies the previous line
SubType.prototype = {
  getSubValue : function (){
    return this.subproperty;
  },
  someOtherMethod : function (){
    return false;
  }
};
var instance = new SubType();
alert(instance.getSuperValue()); //error!

原型鏈的問題:和原型一樣,當使用引用類型值的時候,原型鏈就會出問題了?;仡櫼幌轮暗膬热?,包含一個引用類型值的原型屬性會被所有實例共享,這就是為什么我們要把引用類型值在構造函數中定義,而不是在原型中定義。在通過原型鏈實現繼承時,原型實際上會變成另一個類型的實例,于是,原先的實例屬性也順利成章的變成現在的原型屬性了。
復制代碼 代碼如下:

function SuperType(){
  this.colors = [“red”, “blue”, “green”];
}
function SubType(){
}
//inherit from SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push(“black”);
alert(instance1.colors); //”red,blue,green,black”
var instance2 = new SubType();
alert(instance2.colors); //”red,blue,green,black”

在SuperType構造函數中,我們定義了一個colors數組,每一個SuperType實例都會擁有它自己的這個colors數組。但是當SubType使用原型鏈繼承SuperType以后,SubType.prototype變成SuperType的一個實例,因此它擁有自己的colors屬性,也就是說SubType.prototype.colors屬性。所以,當創建SubType實例的時候,所有實例都共享這一屬性了。如上面的代碼所示。

第二個問題就是:在創建子類的實例時,不能向超類的構造函數中傳遞參數。實際上,應該說是沒有辦法在不影響所有對象實例的情況下,給超類的構造函數傳遞參數。由于這些問題,我們不會單獨使用原型鏈。

--------------------------------------------------------------------------------

借用構造函數(Contructor stealing):
為了解決上述問題,開發人員發明了一種叫做借用構造函數的技術。這種技術的思路就是:在子類型構造函數的內部調用超類型構造函數。(函數,只不過是在特定環境中執行代碼的對象?)我們可以通過使用apply()或call()方法在新創建的對象上執行構造函數。

復制代碼 代碼如下:

function SuperType(){
  this.colors = [“red”, “blue”, “green”];
}
function SubType(){
  //inherit from SuperType
  SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push(“black”);
alert(instance1.colors); //”red,blue,green,black”
var instance2 = new SubType();
alert(instance2.colors); //”red,blue,green”

我們在SubType里使用call()方法調用SuperType的構造函數,實際上就是在新的SubType對象上執行SuperType()函數中定義的所有對象初始化代碼。結果就是每個SubType實例都具有自己的colors屬性的副本。

傳遞參數:使用借用構造函數方法的一個很大的好處在于就是,我們可以從子類的構造函數傳遞參數到父類的構造函數中。

復制代碼 代碼如下:

function SuperType(name){
  this.name = name;
}
function SubType(){
  //inherit from SuperType passing in an argument
  SuperType.call(this, “Nicholas”);
  //instance property
  this.age = 29;
}
var instance = new SubType();
alert(instance.name); //”Nicholas”;
alert(instance.age); //29

新的SuperType構造函數新增了一個參數name,我們在call SuperType的同時,往SuperType傳遞參數"Nicholas"。為了不讓超類型的構造函數重寫子類型的屬性,可以在調用超類型構造函數后再定義子類的屬性。

借用構造函數的問題:方法都在構造函數中定義,無法復用。而且在超類型的原型中定義的方法,對子類型而言是不可見的。結果所有類型都只能使用構造函數模式。

--------------------------------------------------------------------------------

組合繼承:
結合原型鏈及借用構造函數各自的優點的一種繼承模式。使用原型鏈繼承原型屬性及方法,使用借用構造函數來繼承實例屬性。如下面例子,我們使用call()方法調用SuperType的構造函數(每個SubType實例都擁有自己的name和colors屬性,以及SubType的age屬性);然后再把SuperType實例賦值給SubType的原型,使其繼承SuperType的sayName()方法(每個實例都共用這個方法)。

復制代碼 代碼如下:

function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function(){
    alert(this.name);
};

function SubType(name, age){
    //inherit properties
    SuperType.call(this, name);
    this.age = age;
}
//inherit methods
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
    alert(this.age);
};

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27


原型式繼承(Prototypal Inheritance):
復制代碼 代碼如下:

function object(o){
  function F(){}
  F.prototype = o;
  return new F();
}
--------------------------------------------------------------------------------


寄生式繼承(Parasitic Inheritance):

缺點同構造函數

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美最顶级的aⅴ艳星| 久久91亚洲精品中文字幕| 久久久免费精品视频| 81精品国产乱码久久久久久| 欧美成人亚洲成人| 成年无码av片在线| 日韩中文字幕精品视频| 国内精品久久久久久久久| 国产福利精品在线| 亚洲欧美中文日韩在线v日本| 国产97在线亚洲| 欧美日韩在线观看视频小说| 国产视频久久久| 91经典在线视频| 色综合天天狠天天透天天伊人| 成人久久久久爱| 懂色av一区二区三区| 高清欧美性猛交xxxx黑人猛交| 一本色道久久综合狠狠躁篇怎么玩| 欧美激情视频一区二区| 91国内免费在线视频| 成年无码av片在线| 欧美亚洲国产成人精品| 97香蕉超级碰碰久久免费软件| 亚洲日本中文字幕| 91性高湖久久久久久久久_久久99| 97国产精品视频| 日韩经典中文字幕在线观看| 日韩av中文字幕在线| 欧美性生活大片免费观看网址| 亚洲人成电影在线播放| www.亚洲人.com| 中文字幕亚洲情99在线| 亚洲视频在线观看网站| 91在线免费视频| 日韩黄在线观看| 疯狂欧美牲乱大交777| 亚洲午夜久久久久久久| 7m精品福利视频导航| 欧美疯狂xxxx大交乱88av| 国产亚洲a∨片在线观看| 成人黄色在线观看| 尤物精品国产第一福利三区| 欧美黑人视频一区| 91丨九色丨国产在线| 欧美成人性色生活仑片| 国产亚洲精品久久久| 一本色道久久综合狠狠躁篇怎么玩| 亚洲午夜未满十八勿入免费观看全集| 欧美精品一区三区| 中文字幕精品—区二区| 亚洲成人三级在线| www.美女亚洲精品| 日本韩国欧美精品大片卡二| 91高清免费在线观看| 国产日产久久高清欧美一区| 国产欧美日韩精品在线观看| 欧美区二区三区| 欧美性在线观看| 国产一区二区三区视频| 国产欧美最新羞羞视频在线观看| 日韩在线视频国产| 日韩在线观看免费全集电视剧网站| 久久久精品视频成人| 欧美高清一级大片| 欧亚精品中文字幕| 欧美视频二区36p| 日韩av在线资源| 久久中国妇女中文字幕| 亚洲成在人线av| 国产区精品在线观看| 亚洲激情电影中文字幕| 亚洲一区美女视频在线观看免费| 欧美性xxxxxx| 91精品久久久久久久久久另类| 亚洲黄页网在线观看| 最近2019中文字幕mv免费看| 久久久伊人日本| 精品视频—区二区三区免费| 国产欧美精品一区二区三区-老狼| 成人免费视频网| 伊人成人开心激情综合网| 国产亚洲人成a一在线v站| 亚洲国产精品久久久久久| 日韩动漫免费观看电视剧高清| 清纯唯美亚洲激情| 日韩高清电影好看的电视剧电影| 欧美在线视频免费| 成人激情电影一区二区| 国产亚洲免费的视频看| 国产精品久久久亚洲| 久久久久久美女| 欧美成人精品激情在线观看| 97视频在线看| 亚洲成色777777女色窝| 亚洲第一福利网| 欧美精品午夜视频| 日韩一区视频在线| 欧美国产日韩免费| 久久精品国产清自在天天线| 国产成人精品一区二区| 久久国产精品影视| 精品视频在线播放| 国产精品成人va在线观看| 亚洲精品成人久久电影| 欧美日韩中文字幕综合视频| 欧美日韩一区二区三区| 91日本在线视频| 亚洲人成在线免费观看| 国产精品专区一| 久久久精品免费视频| 九九精品在线视频| 久久频这里精品99香蕉| 亚洲第一免费播放区| 日韩欧美在线播放| 日本免费一区二区三区视频观看| 国产精品第一区| 成人国产精品免费视频| 最近2019年手机中文字幕| 色先锋资源久久综合5566| 欧美不卡视频一区发布| 欧美午夜久久久| 成人在线一区二区| 911国产网站尤物在线观看| 日韩在线观看高清| 久久久人成影片一区二区三区观看| 国产亚洲a∨片在线观看| 亚洲天堂免费在线| 国产精品欧美日韩久久| 91麻豆国产精品| 久久久在线免费观看| 久久久久久久999| 久久久在线视频| 亚洲国产日韩欧美在线动漫| 三级精品视频久久久久| 午夜精品久久久久久久99黑人| 日韩精品在线影院| 久久中文字幕在线| 久久久久久亚洲| 久久久久久久久久久国产| 久久久亚洲精品视频| 在线视频一区二区| 精品久久久久久电影| 91精品91久久久久久| 日本欧美黄网站| 欧美性猛交xxxx富婆| 久久99国产精品久久久久久久久| 中文字幕亚洲欧美日韩在线不卡| 亚洲精品久久久久中文字幕二区| 国产精品va在线| 97免费中文视频在线观看| 欧美最顶级丰满的aⅴ艳星| 美女扒开尿口让男人操亚洲视频网站| 亚洲精品一区二区三区婷婷月| 日韩欧美亚洲成人| 欧美丝袜美女中出在线| 伦理中文字幕亚洲| 欧美人与性动交a欧美精品| 97精品国产aⅴ7777| 国产精品稀缺呦系列在线| 中文字幕欧美日韩精品| 日韩美女中文字幕| 97久久精品人搡人人玩| 欧美性精品220|