亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

學(xué)習(xí)javascript面向?qū)ο?javascript實(shí)現(xiàn)繼承的方式

 更新時(shí)間:2016年01月04日 10:07:16   作者:小火柴的藍(lán)色理想  
這篇文章主要為大家介紹了javascript實(shí)現(xiàn)繼承的方式,學(xué)習(xí)javascript面向?qū)ο?,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家介紹了javascript實(shí)現(xiàn)繼承的6種方式,分享給大家供大家參考,具體內(nèi)容如下

1、【原型鏈繼承】實(shí)現(xiàn)的本質(zhì)是重寫(xiě)原型對(duì)象,代之以一個(gè)新類(lèi)型的實(shí)例。實(shí)際上不是SubType的原型的constructor屬性被重寫(xiě)了,而是SubType的原型指向了另一個(gè)對(duì)象——SuperType的原型,而這個(gè)原型對(duì)象的construtor屬性指向的是SuperType

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//繼承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
 return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());//true

[注意1]謹(jǐn)慎地定義方法,給原型添加方法的代碼一定要放在替換原型的語(yǔ)句之后

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//繼承了SuperType
SubType.prototype = new SuperType();

//添加了新方法
SubType.prototype.getSubValue = function(){
 return this.subproperty;
}
//重寫(xiě)超類(lèi)型的方法
SubType.prototype.getSuperValue = function(){
 return false;
}
var instance = new SubType();
alert(instance.getSuperValue());//false

[注意2]通過(guò)原型鏈實(shí)現(xiàn)繼承時(shí),不能使用對(duì)象字面量創(chuàng)建原型方法,這樣做會(huì)重寫(xiě)原型鏈

function SuperType(){
 this.property = true;
}
SuperType.prototype.getSuperValue = function(){
 return this.property;
};
function SubType(){
 this.subproperty = false;
}
//繼承了SuperType
SubType.prototype = new SuperType();

//使用字面量方法添加新方法會(huì)導(dǎo)致上一行代碼無(wú)效
SubType.prototype = {
 getSubValue : function(){
  return this,subproperty;
 },
 someOtherMethod : function(){
  return false;
 }
};
var instance = new SubType();
alert(instance.getSuperValue());//error

[缺點(diǎn)1]在創(chuàng)建子類(lèi)型的實(shí)例時(shí),不能向超類(lèi)型的構(gòu)造函數(shù)中傳遞參數(shù)
[缺點(diǎn)2]包含引用類(lèi)型值的原型屬性會(huì)被所有實(shí)例共享

function SuperType(){
 this.colors = ['red','blue','green'];
}
function SubType(){}
//繼承了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'

2、【借用構(gòu)造函數(shù)繼承(又叫偽造對(duì)象或經(jīng)典繼承)】在子類(lèi)型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類(lèi)型構(gòu)造函數(shù),因此通過(guò)使用apply()和call()方法也可以在將來(lái)新創(chuàng)建的對(duì)象上執(zhí)行構(gòu)造函數(shù)

function SuperType(){
 this.colors = ['red','blue','green'];
}
function SubType(){
 //繼承了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'

[優(yōu)點(diǎn)]傳遞參數(shù)

function SuperType(name){
 this.name = name;
}
function SubType(){
 //繼承了SUperType,同時(shí)還傳遞了參數(shù)
 SuperType.call(this,"Nicholas");
 //實(shí)例屬性
 this.age = 29;
}
var instance = new SubType();
alert(instance.name);//"Nicholas"
alert(instance.age);//29 

[注意]為了確保SuperType構(gòu)造函數(shù)不會(huì)重寫(xiě)子類(lèi)型的屬性,可以在調(diào)用超類(lèi)型構(gòu)造函數(shù)后,再添加應(yīng)該在子類(lèi)型中定義的屬性

function SuperType(name){
 this.name = name;
 this.age = 30;
}
function SubType(){
 //實(shí)例屬性
 this.age = 29;
 //繼承了SUperType,同時(shí)還傳遞了參數(shù)
 SuperType.call(this,"Nicholas");
}
var instance = new SubType();
//實(shí)例屬性被重寫(xiě)為SuperType構(gòu)造函數(shù)的屬性
alert(instance.age);//30

[缺點(diǎn)1]無(wú)法實(shí)現(xiàn)函數(shù)復(fù)用
[缺點(diǎn)2]在超類(lèi)型的原型中定義的方法,對(duì)子類(lèi)型而言也是不可見(jiàn)的,結(jié)果所有類(lèi)型都只能使用構(gòu)造函數(shù)模式
3、【組合繼承(又叫偽經(jīng)典繼承)】將原型鏈和借用構(gòu)造函數(shù)的技術(shù)組合到一起,從而發(fā)揮二者之長(zhǎng)的一種繼承模式。其背后的思路是使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,而通過(guò)借用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。這樣,既通過(guò)在原型上定義方法實(shí)現(xiàn)了函數(shù)復(fù)用,又能夠保證每個(gè)實(shí)例都有它自己的屬性,成為JavaScript中最常用的繼承模式。

function SuperType(name){
 this.name = name;
 this.colors = ['red','blue','green'];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 //繼承屬性
 SuperType.call(this,name);
 this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
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

[缺點(diǎn)]無(wú)論什么情況下,都會(huì)調(diào)用兩次超類(lèi)型構(gòu)造函數(shù):一次是在創(chuàng)建子類(lèi)型原型的時(shí)候,另一次是在子類(lèi)型構(gòu)造函數(shù)內(nèi)部。子類(lèi)型最終會(huì)包含超類(lèi)型對(duì)象的全部實(shí)例屬性,但不得不在調(diào)用子類(lèi)型構(gòu)造函數(shù)時(shí)重寫(xiě)這些屬性。

function SuperType(name){
 this.name = name;
 this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 SuperType.call(this,name); // 第二次調(diào)用SuperType()
 this.age = age;
}
SubType.prototype = new SuperType(); //第一次調(diào)用SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
 alert(this.age);
}; 

4、【原型式繼承】借助原型可以基于已有的對(duì)象創(chuàng)建新對(duì)象,同時(shí)還不必因此創(chuàng)建自定義類(lèi)型。從本質(zhì)上講,object()對(duì)傳入其中的對(duì)象執(zhí)行了一次淺復(fù)制。
  [注意]原型式繼承要求必須有一個(gè)對(duì)象可以作為另一個(gè)對(duì)象的基礎(chǔ),如果有這么一個(gè)對(duì)象的話,可以把它傳遞給object()函數(shù),然后再根據(jù)具體需求對(duì)得到的對(duì)象加以修改即可

function object(o){
  function F(){};
  F.prototype = o;
  return new F();
}
var person = {
  name: "Nicholas",
  friends: ["Shelby","Court","Van"]
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"

【4.1】【Object.create()方法】:ECMAScript5新增Object.create()方法規(guī)范化了原型式繼承。這個(gè)方法接收兩個(gè)參數(shù):一個(gè)用作新對(duì)象原型的對(duì)象和(可選的)一個(gè)為新對(duì)象定義額外屬性的對(duì)象。在傳入一個(gè)參數(shù)情況下,Object.create()與object()方法的行為相同

function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
var person = {
 name: "Nicholas",
 friends:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
alert(person.friends);//"Shelby,Court,Van,Rob,Barbie"

[注意]Object.create()方法的第二個(gè)參數(shù)與Object.defineProperties()方法的第二個(gè)參數(shù)格式相同:每個(gè)屬性都是通過(guò)自己的描述符定義的。以這種方式指定的任何屬性都會(huì)覆蓋原型對(duì)象上的同名屬性。

var person = {
 name: "Nicholas",
 friends:["Shelby","Court","Van"]
};
var anotherPerson = Object.create(person,{
 name: {
  value: "Greg"
 }
});
alert(anotherPerson.name);//"Greg" 

【4.2】低版本瀏覽器下兼容Object.create()方法

if(typeof Object.create != "function"){
 (function(){
  var F = function(){};
  Object.create = function(o){
   if(arguments.length > 1){
    throw Error('Second argument noe supported');
   }
   if(o === null){
    throw Error("Cannot set a null [[Prototype]]");
   }
   if(typeof o != 'Object'){
    throw TypeError("Arguments must be an object");
   }
   F.prototype = o;
   return new F();
  }
 })();
} 

5、【寄生式繼承】創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù),該函數(shù)在內(nèi)部以某種方式來(lái)增強(qiáng)對(duì)象,最后再像真的是它做了所有工作一樣返回對(duì)象
[缺點(diǎn)]無(wú)法實(shí)現(xiàn)函數(shù)復(fù)用

function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
function createAnother(original){
 var clone = object(original);//通過(guò)調(diào)用函數(shù)創(chuàng)建一個(gè)新對(duì)象
 clone.sayHi = function(){ //以某種方式來(lái)增強(qiáng)這個(gè)對(duì)象
  alert("hi");
 };
 return clone;//返回這個(gè)對(duì)象
}
var person = {
 name: "Nicholas",
 friends: ["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();//"hi"

6、【寄生組合式繼承】通過(guò)借用構(gòu)造函數(shù)來(lái)繼承屬性,通過(guò)原型鏈的混成形式來(lái)繼承方法。其背后的基本思路是:不必為了指定子類(lèi)型的原型而調(diào)用超類(lèi)型的構(gòu)造函數(shù),所需的無(wú)非就是超類(lèi)型原型的一個(gè)副本而已。本質(zhì)上,就是使用寄生式繼承來(lái)繼承超類(lèi)型的原型,然后再將結(jié)果指定給子類(lèi)型的原型。寄生組合式繼承是引用類(lèi)型最理想的繼承范式。

//這個(gè)例子中的高效率體現(xiàn)在它只調(diào)用了一次Super構(gòu)造函數(shù),并且因此避免了在SubType.prototype上面創(chuàng)建不必要的、多余的屬性。與此同時(shí),原型鏈還能保持不變。
function object(o){
 function F(){};
 F.prototype = o;
 return new F();
}
function inheritPrototype(subType,superType){
 var prototype = object(superType.prototype);//創(chuàng)建對(duì)象
 prototype.constructor = subType;//增強(qiáng)對(duì)象
 subType.prototype = prototype;//指定對(duì)象
}
function SuperType(name){
 this.name = name;
 this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function(){
 alert(this.name);
};
function SubType(name,age){
 SuperType.call(this,name);
 this.age = age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
 alert(this.age);
}

以上就是本文的全部?jī)?nèi)容,javascript實(shí)現(xiàn)繼承的方式,感謝大家的閱讀,小編會(huì)再接再厲!

相關(guān)文章

最新評(píng)論