call 方法是比常常見(jiàn)也是javascript 難點(diǎn)之一,以前只知道可以實(shí)現(xiàn)繼承,但是沒(méi)有深度研究過(guò)原理,網(wǎng)上大多數(shù)也只是說(shuō)了方法,沒(méi)有講其中的原理,
今天沒(méi)事正好好好研究一下。
call 方法最常見(jiàn)的也是面試問(wèn)題之一是啥,對(duì)就是用call實(shí)現(xiàn)繼承。
以下是兩個(gè)簡(jiǎn)單的實(shí)現(xiàn)繼承的例子。
demo1:
function a(){
??? this.name = function(){
????? ?console.log('a',this.namevalue,this.age)
??? }
}
function b(){
??? a.call(this);??? //這里的this代表b對(duì)象本身
}
var bt = new b();
bt.name();?
demo2:
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
我們可以看到,只需要在b中 添加 a.call(this);然后直接實(shí)例化就可以實(shí)現(xiàn)繼承了,可是為什么呢?
我們先看下官方文檔對(duì)call方法的解釋:
call() 提供新的 this 值給當(dāng)前調(diào)用的函數(shù)/方法。
也就是說(shuō)call 方法將原本a的this對(duì)象替換成了b的this對(duì)象,是不是有點(diǎn)繞口?
但是這樣還是不能解釋為什么bt 可以訪問(wèn)a函數(shù)內(nèi)的方法,a函數(shù)內(nèi)的方法只有a的實(shí)例才可以訪問(wèn)呀,難道a函數(shù)也被實(shí)例化了嘛????
要搞清楚這個(gè)問(wèn)題我們首先還需要知道new 這個(gè)關(guān)鍵字到底做了什么?
function b(){
this.name="b";
this.sayName=()=>{
console.log('this.name',this.name);
}
}
var bt=new b();
console.log(bt);
我們可以看到new 關(guān)鍵字創(chuàng)建了一個(gè)對(duì)象,將所有this關(guān)鍵字的屬性都生成了新對(duì)象的屬性;
也就是說(shuō)new關(guān)鍵字會(huì)將所有的和this有關(guān)的屬性都會(huì)轉(zhuǎn)化為新對(duì)象的屬性,
那么當(dāng)call方法將b的this對(duì)象賦值給a方法時(shí),new 也會(huì)檢測(cè)到:并且當(dāng)做是b的屬性一期實(shí)例化:讓我們來(lái)試驗(yàn)一下。已demo1代碼為例,將b輸出一下:
function a(){
this.namevalue=19;
??? this.name = function(){
??????console.log('a',this.namevalue,this.age)
??? }
}
function b(){
this.age=19;
??? a.call(this);??? //這里的this代表b對(duì)象本身
}
var bt = new b();
console.log(bs)
輸出:
猜測(cè)正確,所以實(shí)現(xiàn)繼承的方式call只是起了個(gè)替換this對(duì)象的作用,主要工作還是在new 關(guān)鍵字,它能自動(dòng)檢測(cè)和this綁定的屬性,全部添加到要實(shí)例化的對(duì)象上面。其實(shí)上面的代碼和下面的代碼效果是一樣的:
function b(){
this.namevalue=19;
??? this.name = function(){
??????console.log('a',this.namevalue,this.age)
??? }
this.age=19;
??? a.call(this);??? //這里的this代表b對(duì)象本身
}
var bs = new b();
console.log(bs)
今天算是對(duì)call 有了更深的理解,完全是自我理解,如果你有不同的見(jiàn)解,歡迎評(píng)論,歡迎打臉指正。
碼字不易點(diǎn)個(gè)贊再走吧。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。