1.js中實(shí)現(xiàn)組合繼承(B繼承A):
function A(name){
? ? this.name = name;
? ??this.colors = ["red", "green", "blue"];
}
A.prototype.say =function()
{
? ? console.log(this.name);
}
function B(name, age){
? ? A.call(this, name); //第二次調(diào)用
? ? this.age = age;
}
B.prototype =new A(); //第一次調(diào)用
B.prototype.constructor = B;
function main(){
var b = new B("hello", 30);
b.say();
}
這種繼承方式主要是利用原型鏈實(shí)現(xiàn)繼承,同時使用構(gòu)造函數(shù)傳入?yún)?shù),每當(dāng)生成B對象時,會調(diào)用A的構(gòu)造函數(shù)添加name和ary屬性從而實(shí)現(xiàn)繼承。
但這種方式有個缺陷,會調(diào)用2次A的構(gòu)造函數(shù),第一次是在設(shè)置prototype時,此時B.prototype指向一個A的實(shí)例,實(shí)例中保存著一份name和ary;第二次是在生成B對象時,B的構(gòu)造函數(shù)會調(diào)用A的構(gòu)造函數(shù),在B對象中添加name和ary屬性,當(dāng)訪問B對象屬性時,發(fā)現(xiàn)B對象中有name和ary,所以返回的值是我們所期望的。
2.寄生組合式繼承(B繼承A):
function create(B, A){
? ? var prototype = object(A.prototype);
? ? B.prototype = prototype;
? ? prototype.constructor = B;
}
function object(o){
? ? function F(){};
? ? F.prototype = o;
? ? return new F();
}
function A(name){
? ? this.name = name;
? ??this.colors = ["red", "green", "blue"];
}
A.prototype.sayName =function()
{
? ? console.log(this.name);
}
function B(name, age){
? ? A.call(this, name);
? ? this.age = age;
}
create(B, A);
B.prototype.sayAge =function()
{
? ? console.log(this.age);
}
function main(){
? ? var instance =new B("hello", 30);
? ? instance.sayName();
? ? instance.sayAge();
}
這種繼承方式跟第一種很相似,區(qū)別就是使用了create方法,首先創(chuàng)建A原型的一個副本,然后將因重寫原型而失去的constructor指向B,最后將新創(chuàng)建的原型副本賦值給B的原型。
優(yōu)點(diǎn)是不會調(diào)用兩次父超類型的構(gòu)造函數(shù),不用創(chuàng)建多余屬性。
參考了網(wǎng)上的文章,不會百度的前端不是好前端。