⑴ JavaScript中繼承應該怎麼實現
1.原型鏈
基本思想:利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。
構造函數,原型,實例之間的關系:每個構造函數都有一個原型對象,原型對象包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。
原型鏈實現繼承例子:
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}
function subType() {
this.property = false;
}
//繼承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
return this.property;
}
var instance = new SubType();
console.log(instance.getSuperValue());//true
2.借用構造函數
基本思想:在子類型構造函數的內部調用超類構造函數,通過使用call()和apply()方法可以在新創建的對象上執行構造函數。
例子:
function SuperType() {
this.colors = ["red","blue","green"];
}
function SubType() {
SuperType.call(this);//繼承了SuperType
}
var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//"red","blue","green","black"
var instance2 = new SubType();
console.log(instance2.colors);//"red","blue","green"
3.組合繼承
基本思想:將原型鏈和借用構造函數的技術組合在一塊,從而發揮兩者之長的一種繼承模式。
例子:
function SuperType(name) {
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function() {
console.log(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() {
console.log(this.age);
}
var instance1 = new SubType("EvanChen",18);
instance1.colors.push("black");
consol.log(instance1.colors);//"red","blue","green","black"
instance1.sayName();//"EvanChen"
instance1.sayAge();//18
var instance2 = new SubType("EvanChen666",20);
console.log(instance2.colors);//"red","blue","green"
instance2.sayName();//"EvanChen666"
instance2.sayAge();//20
4.原型式繼承
基本想法:藉助原型可以基於已有的對象創建新對象,同時還不必須因此創建自定義的類型。
原型式繼承的思想可用以下函數來說明:
function object(o) {
function F(){}
F.prototype = o;
return new F();
}
例子:
var person = {
name:"EvanChen",
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");
console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
ECMAScript5通過新增Object.create()方法規范化了原型式繼承,這個方法接收兩個參數:一個用作新對象原型的對象和一個作為新對象定義額外屬性的對象。
var person = {
name:"EvanChen",
friends:["Shelby","Court","Van"];
};
var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
5.寄生式繼承
基本思想:創建一個僅用於封裝繼承過程的函數,該函數在內部以某種方式來增強對象,最後再像真正是它做了所有工作一樣返回對象。
例子:
function createAnother(original) {
var clone = object(original);
clone.sayHi = function () {
alert("hi");
};
return clone;
}
var person = {
name:"EvanChen",
friends:["Shelby","Court","Van"];
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();///"hi"
6.寄生組合式繼承
基本思想:通過借用函數來繼承屬性,通過原型鏈的混成形式來繼承方法
其基本模型如下所示:
function inheritProperty(subType, superType) {
var prototype = object(superType.prototype);//創建對象
prototype.constructor = subType;//增強對象
subType.prototype = prototype;//指定對象
}
例子:
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;
}
inheritProperty(SubType,SuperType);
SubType.prototype.sayAge = function() {
alert(this.age);
}
⑵ js中有哪些繼承方式
繼承的方式一共有三種:
一、原型繼承
通過prototype 來實現繼承。
function Person(name,age) { this.name=name; this.age=age;
}
Person.prototype.sayHello=function(){
alert (''使用原型得到Name:'' + this.name);
} var per = new Person("馬小倩",21);
per.sayHello();//輸出:使用原型得到Name:馬小倩
function Student(){}
Student.prototype=new Person("洪如彤",21); //實現原型繼承
var stu = new Student();
Student.prototype.grade=5;
Student.prototype.intr=function(){
alert(this.grade);
}
stu.sayHello();//輸出:使用原型得到Name:洪如彤
stu.intr();//輸出:5
二、構造函數實現繼承
function Person(name,age) { this.name=name; this.age=age;
}
Person.prototype.sayHello=function(){
alert (''使用原型得到Name:'' + this.name);
} var per = new Person("馬小倩",21);
per.sayHello();//輸出:使用原型得到Name:馬小倩
三、 通過call、apply 實現繼承
⑶ js中繼承的幾種用法總結
一,js中對象繼承
js中有三種繼承方式
1.js原型(prototype)實現繼承
復制代碼 代碼如下:
<SPAN style="BACKGROUND-COLOR: #ffffff"><SPAN style="FONT-SIZE: 18px"><html>
<body>
<script type="text/javascript">
function Person(name,age){
this.name=name;
this.age=age;
}
Person.prototype.sayHello=function(){
alert("使用原型得到Name:"+this.name);
}
var per=new Person("馬小倩",21);
per.sayHello(); //輸出:使用原型得到Name:馬小倩
function Student(){}
Student.prototype=new Person("洪如彤",21);
var stu=new Student();
Student.prototype.grade=5;
Student.prototype.intr=function(){
alert(this.grade);
}
stu.sayHello();//輸出:使用原型得到Name:洪如彤
stu.intr();//輸出:5
</script>
</body>
</html></SPAN></SPAN>
2.構造函數實現繼承
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 18px"><html>
<body>
<script type="text/javascript">
function Parent(name){
this.name=name;
this.sayParent=function(){
alert("Parent:"+this.name);
}
}
function Child(name,age){
this.tempMethod=Parent;
this.tempMethod(name);
this.age=age;
this.sayChild=function(){
alert("Child:"+this.name+"age:"+this.age);
}
}
var parent=new Parent("江劍臣");
parent.sayParent(); //輸出:「Parent:江劍臣」
var child=new Child("李鳴",24); //輸出:「Child:李鳴 age:24」
child.sayChild();
</script>
</body>
</html></SPAN>
3.call , apply實現繼承
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 18px"><html>
<body>
<script type="text/javascript">
function Person(name,age,love){
this.name=name;
this.age=age;
this.love=love;
this.say=function say(){
alert("姓名:"+name);
}
}
//call方式
function student(name,age){
Person.call(this,name,age);
}
//apply方式
function teacher(name,love){
Person.apply(this,[name,love]);
//Person.apply(this,arguments); //跟上句一樣的效果,arguments
}
//call與aplly的異同:
//1,第一個參數this都一樣,指當前對象
//2,第二個參數不一樣:call的是一個個的參數列表;apply的是一個數組(arguments也可以)
var per=new Person("武鳳樓",25,"魏熒屏"); //輸出:「武鳳樓」
per.say();
var stu=new student("曹玉",18);//輸出:「曹玉」
stu.say();
var tea=new teacher("秦傑",16);//輸出:「秦傑」
tea.say();
</script>
</body>
</html></SPAN>
二、call和apply的用法(詳細介紹)
js中call和apply都可以實現繼承,唯一的一點參數不同,func.call(func1,var1,var2,var3)對應的apply寫法為:func.apply(func1,[var1,var2,var3])。
JS手冊中對call的解釋:
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 18px">call 方法
調用一個對象的一個方法,以另一個對象替換當前對象。
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
參數
thisObj
可選項。將被用作當前對象的對象。
arg1, arg2, , argN
可選項。將被傳遞方法參數序列。
說明
call 方法可以用來代替另一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變為由 thisObj 指定的新對象。
如果沒有提供 thisObj 參數,那麼 Global 對象被用作 thisObj。</SPAN>
說簡單一點,這兩函數的作用其實就是更改對象的內部指針,即改變對象的this指向的內容。這在面向對象的js編程過程中有時是很有用的。下面以apply為例,說說這兩個函數在 js中的重要作用。如:
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 18px"> function Person(name,age){ //定義一個類
this.name=name; //名字
this.age=age; //年齡
this.sayhello=function(){alert(this.name)};
}
function Print(){ //顯示類的屬性
this.funcName="Print";
this.show=function(){
var msg=[];
for(var key in this){
if(typeof(this[key])!="function"){
msg.push([key,":",this[key]].join(""));
}
}
alert(msg.join(" "));
};
}
function Student(name,age,grade,school){ //學生類
Person.apply(this,arguments);//比call優越的地方
Print.apply(this,arguments);
this.grade=grade; //年級
this.school=school; //學校
}
var p1=new Person("卜開化",80);
p1.sayhello();
var s1=new Student("白雲飛",40,9,"嶽麓書院");
s1.show();
s1.sayhello();
alert(s1.funcName);</SPAN>
另外,Function.apply()在提升程序性能方面有著突出的作用:
我們先從Math.max()函數說起,Math.max後面可以接任意個參數,最後返回所有參數中的最大值。
比如
復制代碼 代碼如下:
<SPAN style="FONT-SIZE: 18px">alert(Math.max(5,8)); //8
alert(Math.max(5,7,9,3,1,6)); //9
//但是在很多情況下,我們需要找出數組中最大的元素。
var arr=[5,7,9,1];
//alert(Math.max(arr)); // 這樣卻是不行的。NaN
//要這樣寫
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0];i<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
alert(getMax(arr)); //9
//換用apply,可以這樣寫
function getMax2(arr){
return Math.max.apply(null,arr);
}
alert(getMax2(arr)); //9
//兩段代碼達到了同樣的目的,但是getMax2卻優雅,高效,簡潔得多。
//再比如數組的push方法。
var arr1=[1,3,4];
var arr2=[3,4,5];
//如果我們要把 arr2展開,然後一個一個追加到arr1中去,最後讓arr1=[1,3,4,3,4,5]
//arr1.push(arr2)顯然是不行的。 因為這樣做會得到[1,3,4,[3,4,5]]
//我們只能用一個循環去一個一個的push(當然也可以用arr1.concat(arr2),但是concat方法並不改變arr1本身)
var arrLen=arr2.length;
for(var i=0;i<arrLen;i++){
arr1.push(arr2[i]);
}
//自從有了Apply,事情就變得如此簡單
Array.prototype.push.apply(arr1,arr2); //現在arr1就是想要的結果</SPAN>
⑷ js寫一個方法,用於實現繼承功能.怎麼寫
function Parent(firstname)
{
this.fname=firstname;
this.age=40;
this.sayAge=function()
{
console.log(this.age);
}
}
function Child(firstname)
{
this.parent=Parent;
this.parent(firstname);
delete this.parent;
this.saySomeThing=function()
{
console.log(this.fname);
this.sayAge();
}
}
var mychild=new Child("李");
mychild.saySomeThing();
⑸ 一個JS如何繼承在不同文件中的另一個JS
由於javascript的類是源於function實現的,而這個function即代表類又代表了此類的構造函數。
var
a=function(b){}是定義在類中的一個函數。
prototype屬性是用於繼承類,如果有一個類為a,另一個類為b,如想b類繼承a類,那麼必須在b類中的prototype屬性設置為a,即prototype=a;
⑹ 關於javascript的子類方法如何繼承全部父類的方法(有特殊條件)
看你這個樣子是有點強迫症,放到裡面是沒有問題的,至於你說的開銷,你完全是想太多。因為你這個有構造函數參數,不能使用常規的方法。至於你為什麼報錯,是因為Animal.apply(this,arguments)並沒有將Animal附加到Cat的原型鏈上,而你的move是在Animal的原型鏈上。你加一句:Cat.prototype=Animal.prototype,可以達到你想要的效果,但這個開銷問題,有太多區別嗎?我沒有測試,你可以測試一下,呵呵。
⑺ js實現繼承的幾種方法
《繼承法》第二十三條 繼承開始後,知道被繼承人死亡的繼承人應當及時通知其他繼承人和遺囑執行人。繼承人中無人知道被繼承人死亡或者知道被繼承人死亡而不能通知的,由被繼承人生前所在單位或者住所地的居民委員會、村民委員會負責通知。第二十四條 存有遺產的人,應當妥善保管遺產,任何人不得侵吞或者爭搶。第二十五條 繼承開始後,繼承人放棄繼承的,應當在遺產處理前,作出放棄繼承的表示。沒有表示的,視為接受繼承。受遺贈人應當在知道受遺贈後兩個月內,作出接受或者放棄受遺贈的表示,到期沒有表示的,視為放棄受遺贈。第二十六條 夫妻在婚姻關系存續期間所得的共同所有的財產,除有約定的以外,如果分割遺產,應當先將共同所有的財產的一半分出為配偶所有,其餘的為被繼承人的遺產。遺產在家庭共有財產之中的,遺產分割時,應當先分出他人的財產。第二十七條 有下列情形之一的,遺產中的有關部分按照法定繼承辦理:遺囑繼承人放棄繼承或者受遺贈人放棄受遺贈的;遺囑繼承人喪失繼承權的;遺囑繼承人、受遺贈人先於遺囑人死亡的;遺囑無效部分所涉及的遺產;遺囑未處分的遺產。第二十八條 遺產分割時,應當保留胎兒的繼承份額。胎兒出生時是死體的,保留的份額按照法定繼承辦理。第二十九條 遺產分割應當有利於生產和生活需要,不損害遺產的效用。不宜分割的遺產,可以採取折價、適當補償或者共有等方法處理。第三十條 夫妻一方死亡後另一方再婚的,有權處分所繼承的財產,任何人不得干涉。第三十一條 公民可以與扶養人簽訂遺贈扶養協議。按照協議,扶養人承擔該公民生養死葬的義務,享有受遺贈的權利。公民可以與集體所有制組織簽訂遺贈扶養協議。按照協議,集體所有制組織承擔該公民生養死葬的義務,享有受遺贈的權利。第三十二條無人繼承又無人受遺贈的遺產,歸國家所有;死者生前是集體所有制組織成員的,歸所在集體所有制組織所有。第三十三條 繼承遺產應當清償被繼承人依法應當繳納的稅款和債務,繳納稅款和清償債務以他的遺產實際價值為限。超過遺產實際價值部分,繼承人自願償還的不在此限。繼承人放棄繼承的,對被繼承人依法應當繳納的稅款和債務可以不負償還責任。第三十四條 執行遺贈不得妨礙清償遺贈人依法應當繳納的稅款和債務。
⑻ js繼承的幾種方式 各
js繼承用的還是比較少的,一般通過原型鏈繼承或混合繼承目的就是降低創建對象的開銷!
各種繼承示例如下:
<script>
//把父類方法放到其原型鏈中而非類聲明體中,以便每次實例化子類時不至於都執行函數而增加創建對象的開銷
Person.prototype.speakP=function(){
console.log("I'maPerson!");
};
functionPerson(age,name){
this.age=age;
this.name=name;
}
functionStudent(sno,age,name){
Person.call(this,age,name);
this.sno=sno;
}
vars=newStudent(95001,23,"小紅");
console.log(Student.prototype.constructor);
//s.speakP();//s不是Person類型,所以不能調用speakP函數;如果非要調用,可使用以下方案二:原型鏈繼承
</script>
<script>
Person.prototype.speakP=function(){
console.log("I'maPerson!age="+this.age+"name="+this.name);//通過實例化的子類對象調用我時獲取不到父類的age、name
};
functionPerson(age,name){
this.age=age;
this.name=name;
}
Student.prototype=newPerson();
//因為修改了Student原型鏈,需要把其原型鏈上構造器重新指向自己
Student.prototype.constructor=Student;
functionStudent(sno,age,name){
this.sno=sno;
}
vars=newStudent(95001,23,"小紅");
console.log(Student.prototype.constructor);
s.speakP();
</script>
<script>
Person.prototype.speakP=function(){
console.log("I'maPerson!age="+this.age+"name="+this.name);
};
functionPerson(age,name){
this.age=age;
this.name=name;
}
Student.prototype=newPerson();
Student.prototype.constructor=Student;
functionStudent(sno,age,name){
Person.call(this,age,name);
this.sno=sno;
}
vars=newStudent(95001,23,"小紅");
console.log(Student.prototype.constructor);
s.speakP();
</script>
<script>
classPerson{
constructor(age,name){
this.age=age;
this.name=name;
}
sayHi(){
console.log("I'maPerson!age="+this.age+"name="+this.name);
}
}
classStudentextendsPerson{
constructor(sno,age,name){
super(age,name);
this.sno=sno;
}
}
vars=newStudent(95001,24,"小紅");
console.log(Student.prototype.constructor);
s.sayHi();
</script>
⑼ javascript中如何實現類的繼承啊
js繼承有5種實現方式:
1、繼承第一種方式:對象冒充
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
function Child(username,password){
//通過以下3行實現將Parent的屬性和方法追加到Child中,從而實現繼承
//第一步:this.method是作為一個臨時的屬性,並且指向Parent所指向的對象,
//第二步:執行this.method方法,即執行Parent所指向的對象函數
//第三步:銷毀this.method屬性,即此時Child就已經擁有了Parent的所有屬性和方法
this.method = Parent;
this.method(username);//最關鍵的一行
delete this.method;
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("zhangsan");
var child = new Child("lisi","123456");
parent.hello();
child.hello();
child.world();
2、繼承第二種方式:call()方法方式
call方法是Function類中的方法
call方法的第一個參數的值賦值給類(即方法)中出現的this
call方法的第二個參數開始依次賦值給類(即方法)所接受的參數
function test(str){
alert(this.name + " " + str);
}
var object = new Object();
object.name = "zhangsan";
test.call(object,"langsin");//此時,第一個參數值object傳遞給了test類(即方法)中出現的this,而第二個參數"langsin"則賦值給了test類(即方法)的str
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
function Child(username,password){
Parent.call(this,username);
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("zhangsan");
var child = new Child("lisi","123456");
parent.hello();
child.hello();
child.world();
3、繼承的第三種方式:apply()方法方式
apply方法接受2個參數,
A、第一個參數與call方法的第一個參數一樣,即賦值給類(即方法)中出現的this
B、第二個參數為數組類型,這個數組中的每個元素依次賦值給類(即方法)所接受的參數
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
function Child(username,password){
Parent.apply(this,new Array(username));
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("zhangsan");
var child = new Child("lisi","123456");
parent.hello();
child.hello();
child.world();
4、繼承的第四種方式:原型鏈方式,即子類通過prototype將所有在父類中通過prototype追加的屬性和方法都追加到Child,從而實現了繼承
function Person(){
}
Person.prototype.hello = "hello";
Person.prototype.sayHello = function(){
alert(this.hello);
}
function Child(){
}
Child.prototype = new Person();//這行的作用是:將Parent中將所有通過prototype追加的屬性和方法都追加到Child,從而實現了繼承
Child.prototype.world = "world";
Child.prototype.sayWorld = function(){
alert(this.world);
}
var c = new Child();
c.sayHello();
c.sayWorld();
5、繼承的第五種方式:混合方式
混合了call方式、原型鏈方式
function Parent(hello){
this.hello = hello;
}
Parent.prototype.sayHello = function(){
alert(this.hello);
}
function Child(hello,world){
Parent.call(this,hello);//將父類的屬性繼承過來
this.world = world;//新增一些屬性
}
Child.prototype = new Parent();//將父類的方法繼承過來
Child.prototype.sayWorld = function(){//新增一些方法
alert(this.world);
}
var c = new Child("zhangsan","lisi");
c.sayHello();
c.sayWorld();
⑽ 關於JS實現繼承的方法都有哪一些
定義一個父類:
// 定義一個動物類
function Animal (name) {
// 屬性
this.name = name || 『Animal』;
// 實例方法
this.sleep = function(){
console.log(this.name + 『正在睡覺!』);
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + 『正在吃:』 + food);
1.原型鏈繼承
核心:將父類的實例作為子類的原型
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 『cat』;
//Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat(『fish』));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
特點:
1.非常純粹的繼承關系,實例是子類的實例,也是父類的實例
2.父類新增的原型方法、屬性,子類都能訪問到
3.簡單,易於實現
缺點:
1.要想為子類新增屬性和方法,必須要在new Animal()這樣的語句之後執行
(可以在cat構造函數中,為Cat實例增加實例屬性)
2.無法實現多繼承
3.來自原型對象的引用屬性被所有實例共享
4.創建子類實例時,無法向父類構造函數傳參
下面代碼解釋缺點3(注意是引用屬性):
function Super(){
this.val = 1;
this.arr = [1];
}
function Sub(){
// ...
}
Sub.prototype = new Super(); // 核心
var sub1 = new Sub();
var sub2 = new Sub();
sub1.val = 2;
sub1.arr.push(2);
alert(sub1.val); // 2
alert(sub2.val); // 1
alert(sub1.arr); // 1, 2
alert(sub2.arr); // 1, 2
2.構造繼承
核心:使用父類的構建函數來增強子類實例,等於復制父類的實例屬性給子類(沒用到原型),除了call方法,也可以用apply()
function Cat(name){
Animal.call(this);
this.name = name || 『Tom』;
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
特點:
1.解決了1中,子類實例共享父類引用屬性的問題
2.創建子類實例時,可以向父類傳遞參數
3.可以實現多繼承(call多個父類對象)
缺點:
1.實例並不是父類的實例,只是子類的實例
2.只能繼承父類的實例屬性和方法,不能繼承原型屬性和方法
3.無法實現函數復用,每個子類都有父類的實例函數的副本,影響性能
3.實例繼承
核心:為父類實例添加新特性,作為子類實例返回
function Cat(name){
var instance = new Animal();
instance.name = name || 『Tom』;
return instance;
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false
特點:
1.不限制調用方式,不管是new 子類()還是子類(),返回的對象都具有相同的效果
缺點:
1.實例是父類的實例,不是子類的實例
2.不支持多繼承
4. 拷貝繼承
核心:使用for…in將父類實例中的方法賦給子類實例
unction Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name || 『Tom』;
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
特點:
1.支持多繼承
缺點:
1.效率較低,內存佔用高(因為要拷貝父類的屬性)
2.無法獲取父類不可枚舉的方法(for in無法訪問不可枚舉的方法)
5.組合繼承
核心:通過調用父類構造,繼承父類的屬性並保留傳參的優點,然後通過將父類實例作為子類原型,實現函數復用
function Cat(name){
Animal.call(this);
this.name = name || 『Tom』;
}
Cat.prototype = new Animal();
//組合繼承需要修復構造函數的指向
Cat.prototype.constructor=Cat;
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
特點:
1.彌補了方式2的缺陷,可以繼承實例屬性、方法,也可以繼承原型屬性、方法
2.既是子類的實例,也是父類的實例
3.不存在引用屬性的共享問題
4.可傳參
5.函數可復用
缺點:
1.調用了兩次父類構造函數,生成了兩份實例(子類實例將子類原型上的那份屏蔽了)
6.寄生組合繼承
核心:通過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點
function Cat(name){
Animal.call(this);
this.name = name || 『Tom』;
}
(function(){
// 創建一個沒有實例方法的類
var Super = function(){};
Super.prototype = Animal.prototype;
//將實例作為子類的原型
Cat.prototype = new Super();
//寄生組合繼承需要修復構造函數的指向
Cat.prototype.constructor=Cat;
})();
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
特點:
1.堪稱完美
缺點:
1.實現較為復雜 (BY三人行慕課)