1.原型鏈
2.call繼承 Fn.call(this) 將Fn中的this替換
// 2.改進(jìn) 不采用原生鏈 改變指向
function Parent() {
this.name ='xiaoer';
this.arr = [1];
this.say = function () {
console.log('haha');
return 10;
}
}
function Child() {
Parent.call(this)
}
// 那么創(chuàng)建的所有的子類(lèi)的實(shí)例其實(shí)創(chuàng)建的相同于父親的實(shí)例
var c1 = new Child();
var c2 = new Child();
c1.name = 'sb';
c1.arr.push(2);
console.log(c1.arr);
console.log(c2.name);
console.log(c1.say());
// 因?yàn)閯?chuàng)建的是兩個(gè)父親的實(shí)例因此引用型的數(shù)據(jù)互補(bǔ)影響
// 借父類(lèi)的構(gòu)造函數(shù)來(lái)增強(qiáng)子類(lèi)實(shí)例蚁阳,等于是把父類(lèi)的實(shí)例屬性復(fù)制了一份給子類(lèi)實(shí)例裝上了(完全沒(méi)有用到原型)
// 無(wú)法實(shí)現(xiàn)函數(shù)復(fù)用姓迅,每個(gè)子類(lèi)實(shí)例都持有一個(gè)新的fun函數(shù)晓殊,太多了就會(huì)影響性能,內(nèi)存爆炸。。
3.冒充對(duì)象繼承
function Parent() {
this.name = 'xiaoer';
this.age = 10;
}
Parent.prototype.height = 20;
function Child() {
var temp = new Parent();
for(var key in temp) {
if (temp.propertyIsEnumerable(key)) {
this[key] = temp[key];
}
}
temp = null;
}
var p = new Child();
特點(diǎn):父類(lèi)私有的和共有的都可以拿到
4.混合模式繼承
function Parent() {
this.name = 'xiaoer';
this.speak = function () {
console.log('english');
}
}
function Child() {
Parent.call(this)
}
Child.prototype = new Parent();
Child.constructor = Parent;
var p = new Child();
特點(diǎn):子類(lèi)的私有和公有有2份屬性 父類(lèi)對(duì)象執(zhí)行了2次
5.寄生組合模式繼承
function Parent() {
this.name = 'xiaoer';
}
Parent.prototype.height = 200;
function Child() {
Parent.call(this)
}
Child.prototype = Create(Parent.prototype);
var p = new Child();
function Create(o) {
function Fn() {}
Fn.prototype = o;
return new Fn;
}
特點(diǎn): 子類(lèi)不僅繼承了父類(lèi)的私有的方法,而且子類(lèi)的原型也僅僅繼承了父類(lèi)原型的方法
- 中間類(lèi)繼承法 不兼容 直接更改原型指向
function haha() {
arguments.__proto__ = new Array();
arguments.reverse();
console.log(arguments);
}
haha(1,34,'xs');