node.js中一切都是對(duì)象,那理所當(dāng)然的函數(shù)也是一個(gè)對(duì)象,是對(duì)象就會(huì)有自己的方法,所有的函數(shù)都少不了這三個(gè)方法,call,apply,bind。
成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的原平網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!我個(gè)人學(xué)完這三個(gè)方法之后有一點(diǎn)自己自己的理解,我的理解就是這三個(gè)方法都是為了綁定this對(duì)象并執(zhí)行該函數(shù)。當(dāng)然三個(gè)方法也有不同之處,我先來說說相同的地方,也就是如何綁定this對(duì)象的。
call:
//代碼1 'use strict'; function test(xx,yy){ this.x = xx; this.y = yy; } let a = {}; test.call(a,10,20); console.log(a); //{x:10,y:20}
如上代碼,我用了ES6的let,"use strict"是開啟了嚴(yán)格模式,然后定義一個(gè)函數(shù)test,有兩個(gè)參數(shù)xx,yy,然后定義了一個(gè)對(duì)象a,沒有屬性,當(dāng)執(zhí)行test.call(a,10,20);這句代碼的時(shí)候就會(huì)把a(bǔ)傳到函數(shù)test里并和this綁定,然后傳參數(shù)10和20,這樣就相當(dāng)于
//代碼2 let a = {}; function test(xx,yy){ a.x = xx; a.y = yy; } test(10,20); console.log(a); //{x:10,y:20}
于是,a對(duì)象就有了 x 和y屬性。
再看apply:
//代碼3 'use strict'; function test(xx,yy){ this.x = xx; this.y = yy; } let a = {}; test.apply(a,[10,20]); console.log(a);//{x:10,y:20}
這段代碼和上面的基本上一樣,只有一句不一樣的:
test.apply(a,[10,20]);
它實(shí)際上也是相當(dāng)于代碼2的,在這里,相信大家也能看出來call 和apply 的區(qū)別了,就是傳參方式不太一樣,call方法是先傳一個(gè)對(duì)象和this綁定,然后再依次傳入test函數(shù)所需要的參數(shù),而apply是先傳一個(gè)對(duì)象和this綁定,然后把test函數(shù)所需要的參數(shù)都打包到一個(gè)數(shù)組中,由apply方法去展開數(shù)組再依次傳入test方法。他們兩個(gè)的區(qū)別就在這。
下面再看bind:
function test(xx,yy){ this.x = xx; this.y = yy; } let a = {}; let b = test.bind(a,10,20); b(); console.log(a);//{x:10,y:20}
和上面兩個(gè)兄弟不一樣的地方在于
let b = test.bind(a,10,20); b();
bind的傳參方式是和call一樣的,但他會(huì)返回一個(gè)函數(shù)存于b中,而b函數(shù)你完全可以不用立即執(zhí)行,這也是bind和call,apply不同的地方。
關(guān)于這點(diǎn)我有一些個(gè)人理解,當(dāng)執(zhí)行了let b = test.bind(a,10,20);之后,實(shí)際上應(yīng)該是返回了一個(gè)函數(shù)對(duì)象,于是上面兩行代碼就可以大致看做:
let b = function test(xx=10,yy=20){ a.x = xx; a.y = yy; }
然后執(zhí)行b();a就會(huì)多了兩個(gè)屬性x,y,這兩個(gè)屬性也有了值10和20,在這里需要重點(diǎn)說一下,如果不執(zhí)行b();a是不會(huì)有變化的。
在本文最開始說在js中一切都是對(duì)象,于是我就有了一個(gè)奇怪的想法,既然b也是一個(gè)函數(shù),那他應(yīng)該也會(huì)有bind方法吧,于是我就又繼續(xù)寫了如下代碼:
'use strict'; function func(name,xx,yy){ this.name = name; this.x = xx; this.y = yy; } let a = {}; let b = {}; let d = func.bind(a,'a',10,20); d(); let f = d.bind(b,'b',10,20); f(); console.log(a,b);
你猜結(jié)果會(huì)如何?會(huì)不會(huì){name:'a',x:10,y:20}{name:'b',x:10,y:20}呢?結(jié)果....果然出乎我的意料:{name:'a',x:10,y:20}{},后來我仔細(xì)想想這是為什么,恩,于是我就想到
let b = function test(xx=10,yy=20){ a.x = xx; a.y = yy; }
這一段,既然函數(shù)里面的this已經(jīng)是a了,那就沒有this了,再傳b進(jìn)去也綁不了this了,所以b才會(huì)沒有屬性。
關(guān)于這一點(diǎn)不知道我想的對(duì)不對(duì),希望有大神能給予指點(diǎn)。本文參考http://developer.51cto.com/art/201503/466978.htm
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。