您好,登錄后才能下訂單哦!
node.js中一切都是對象,那理所當然的函數也是一個對象,是對象就會有自己的方法,所有的函數都少不了這三個方法,call,apply,bind。
我個人學完這三個方法之后有一點自己自己的理解,我的理解就是這三個方法都是為了綁定this對象并執行該函數。當然三個方法也有不同之處,我先來說說相同的地方,也就是如何綁定this對象的。
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"是開啟了嚴格模式,然后定義一個函數test,有兩個參數xx,yy,然后定義了一個對象a,沒有屬性,當執行test.call(a,10,20);這句代碼的時候就會把a傳到函數test里并和this綁定,然后傳參數10和20,這樣就相當于
//代碼2 let a = {}; function test(xx,yy){ a.x = xx; a.y = yy; } test(10,20); console.log(a); //{x:10,y:20}
于是,a對象就有了 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]);
它實際上也是相當于代碼2的,在這里,相信大家也能看出來call 和apply 的區別了,就是傳參方式不太一樣,call方法是先傳一個對象和this綁定,然后再依次傳入test函數所需要的參數,而apply是先傳一個對象和this綁定,然后把test函數所需要的參數都打包到一個數組中,由apply方法去展開數組再依次傳入test方法。他們兩個的區別就在這。
下面再看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}
和上面兩個兄弟不一樣的地方在于
let b = test.bind(a,10,20); b();
bind的傳參方式是和call一樣的,但他會返回一個函數存于b中,而b函數你完全可以不用立即執行,這也是bind和call,apply不同的地方。
關于這點我有一些個人理解,當執行了let b = test.bind(a,10,20);之后,實際上應該是返回了一個函數對象,于是上面兩行代碼就可以大致看做:
let b = function test(xx=10,yy=20){ a.x = xx; a.y = yy; }
然后執行b();a就會多了兩個屬性x,y,這兩個屬性也有了值10和20,在這里需要重點說一下,如果不執行b();a是不會有變化的。
在本文最開始說在js中一切都是對象,于是我就有了一個奇怪的想法,既然b也是一個函數,那他應該也會有bind方法吧,于是我就又繼續寫了如下代碼:
'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);
你猜結果會如何?會不會{name:'a',x:10,y:20}{name:'b',x:10,y:20}呢?結果....果然出乎我的意料:{name:'a',x:10,y:20}{},后來我仔細想想這是為什么,恩,于是我就想到
let b = function test(xx=10,yy=20){ a.x = xx; a.y = yy; }
這一段,既然函數里面的this已經是a了,那就沒有this了,再傳b進去也綁不了this了,所以b才會沒有屬性。
關于這一點不知道我想的對不對,希望有大神能給予指點。本文參考http://developer.51cto.com/art/201503/466978.htm
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。