今天主要說原型鏈繼承、構造繼承、組合繼承三種經常使用繼承方式,分享一下個人理解。數組
//原型繼承
function A(name){
this.name = name;
}
function B(){
this.school = "alb"
}
B.prototype = new A();
B.prototype.age = "112";
var b = new B();
console.log(b);
console.log(b.age);
console.log(b.name);
console.log(b.school);
console.log(b instanceof A);
結果以下:this
註釋:prototype
一、b instanceof A
結果是true 表明b是A原型鏈上code
function A(name){
this.name = name;
}
function B(name,age){
A.call(this,name);
this.age = age;
}
var b = new B("lar","12");
console.log(b);
console.log(b.age);
console.log(b.name);
console.log(b instanceof A);
結果以下:對象
註釋:
一、b instanceof A
結果是false 表明b不是A原型鏈上繼承
舉一個同事和我說的例子:假設一個父類,有100個方法,建立兩個個子類實例內存
原型鏈繼承:
(1)聲明階段:佔用空間爲1個類名+100個方法名 = 101
(2)建立實例階段:佔用空間爲2個類名,加上父類的方法 = 100+2=102原型鏈
構造繼承:
(1)聲明階段:佔用空間爲1個類名 = 1
(2)建立實例階段:兩個子類分別擁有了父類的100個方法,而後加上1個類名 =100+100+1=201原型
原型鏈繼承的優勢:因此以此得出原型鏈繼承相對構造繼承能夠節省空間。父類至關於一個公用代碼,其餘分別進行調用 比每一個方法中都重寫一遍公共代碼好io
function A(name){
this.name = name;
this.arr = [];
}
function B(){
}
B.prototype = new A();
var b = new B();
var c = new B();
b.name = "12";
b.arr.push("111111")
console.log(b);
console.log(b.name);
console.log(b.arr);
console.log(c);
console.log(c.name);
console.log(c.arr);
結果以下:
function A(name){
this.name = name;
this.arr = [];
}
function B(){
A.call(this);
}
var b = new B();
var c = new B();
b.name = "12";
b.arr.push("111111")
console.log(b);
console.log(b.name);
console.log(b.arr);
console.log(c);
console.log(c.name);
console.log(c.arr);
結果以下:
現象:改變b實例時,c的arr變化
原型鏈繼承:因爲數組是父類引用類對象,指向的內存是父類,因此當其中一個子類改變時,父類自動改變,則另外一個子對象也會隨之受影響
構造繼承:構造繼承是已經新建立了一個內存,因此當一個子類改變的時候不會影響到其餘子類已經父類
優缺點比較:由此例子能夠看出,在這種狀況下,構造繼承中的兩個實例是互不影響的,可是原型鏈繼承因爲共用了父類的屬性方法,會受影響
function A(name){
this.name = name;
this.arr = [];
}
function B(){
A.call(this);
}
B.prototype = new A();
var b = new B()
console.log(b);
結果以下:
註釋:
這種狀況下的繼承是即實現了原型鏈繼承,又實現了構造繼承。只是構造繼承的會覆蓋原型鏈繼承,尋找屬性方法會先到構造繼承產生的屬性中,沒有了再找到原型鏈上
function A(name){
this.name = name;
this.arr = [];
}
function B(){
A.call(this);
}
B.prototype = new A();
var b = new B();
var c = new B();
b.name = "12";
b.arr.push("111111")
console.log(b);
console.log(c);
結果以下:
註釋:
以上可見這種狀況下的繼承是最好的,推薦使用這個,惟一的缺點就是生成了兩次實例,浪費了空間