call實(shí)現(xiàn)繼承
call這里call的意思就是把a(bǔ)nimal的方法應(yīng)用到cat這個(gè)對(duì)象身上酣难,也就是animal的屬性創(chuàng)建到了cat里面,所以cat就繼承了animal的方法
function animal(a, b) {
this.type = 'animal'
this.behavior = function(){
console.log(this.type+" is running")
}
}
function cat(a, b) {
this.name = 'wsscat'
//這里call的意思就是把a(bǔ)nimal的方法應(yīng)用到cat這個(gè)對(duì)象身上
//所以cat就繼承了animal的方法
animal.call(this);
}
console.log(new cat())
call實(shí)現(xiàn)多重繼承
當(dāng)然我們可以繼承多個(gè)構(gòu)造函數(shù)兽泣,這就是多重繼承
function animal(a, b) {
this.type = 'animal'
this.behavior = function(){
console.log(this.type+" is running")
}
}
function wsscat(a, b) {
this.age = 0
}
function cat(a, b) {
this.name = 'wsscat'
//這里call的意思就是把a(bǔ)nimal的方法應(yīng)用到cat這個(gè)對(duì)象身上
//所以cat就繼承了animal的方法
animal.call(this);
wsscat.call(this);
}
console.log(new cat())
只要在cat的構(gòu)造函數(shù)中有多個(gè)call就可以,此時(shí)的cat繼承了wsscat和animal
apply和call的區(qū)別
其實(shí)apply和call這兩個(gè)方法基本上是差不多的赂摆,區(qū)別在于call的第二個(gè)參數(shù)可以是任意類型相满,而apply的第二個(gè)參數(shù)必須是數(shù)組据某,也可以是arguments(即傳給構(gòu)造函數(shù)的參數(shù))
例如我們把上面的代碼稍微改一下,如果此時(shí)我在new構(gòu)造函數(shù)cat的時(shí)候傳入?yún)?shù)new cat('wsscat','cute')
我們的cat能接收arguments寄纵,但是如果此時(shí)繼承是animal.call(this)
鳖敷,沒有給call傳第二個(gè)參數(shù)的時(shí)候,生成的對(duì)象中type的值就會(huì)是undefined程拭,所以為了讓這個(gè)值能夠讓animal接收定踱,我們可以在animal中傳入第二個(gè)參數(shù)animal.call(this,type)
function animal(type) {
this.type = type
this.behavior = function(){
console.log(this.type+" is running")
}
}
function cat(name, type) {
this.name = name
//這里call的意思就是把a(bǔ)nimal的方法應(yīng)用到cat這個(gè)對(duì)象身上
//所以cat就繼承了animal的方法
//animal.call(this);//type undefined
//animal.call(this,type);//type cute
//animal.call(this,arguments[1]);//type cute
//animal.call(this,arguments);//type ['wsscat','cute']
animal.apply(this,arguments)//type: wsscat
}
console.log(new cat('wsscat','cute'))
這里用apply就很方便,因?yàn)閍rguments是數(shù)組恃鞋,可以全部傳給animal崖媚,而call就要一個(gè)個(gè)地傳過去
- animal.call(this);//type undefined
- animal.call(this,type);//type cute
- animal.call(this,arguments[1]);//type cute
- animal.call(this,arguments);//type ['wsscat','cute']
- animal.apply(this,arguments)//type: wsscat
繼承的優(yōu)化
如果構(gòu)造函數(shù)this綁定太多屬性(比如一些共同方法)亦歉,在實(shí)例化后會(huì)造成浪費(fèi),為此我們一般會(huì)使用原型鏈來優(yōu)化畅哑,但是使用原型鏈之后我們的apply和call的繼承方法就會(huì)失效
為此我們一般使用混合的寫法肴楷,使用原型鏈和(apply或者call)方法進(jìn)行繼承
具體兩句話
讓子的原型鏈指向父的實(shí)例(父實(shí)例化的對(duì)象)
cat.prototype = new animal();
讓父的屬性創(chuàng)建在子的this上
animal.call(this, type)
整體代碼如下,那么就會(huì)讓父原型鏈的屬性和this上的屬性都得到繼承
function animal(type) {
this.type = type
this.behavior = function() {
console.log(this.type + " is running")
}
}
animal.prototype.action = function() {
console.log("running")
}
function cat(name, type) {
this.name = name
animal.call(this, type)
}
cat.prototype = new animal();
console.log(new cat('wsscat', 'cute'));
(new cat('wsscat')).action() //running