javascript中bind綁定接收者與函數柯里化

若是我要遍歷一個數組,
我只要給forEach傳一個匿名函數便可,很簡單;數組

let arr = ['a', 'b', 'c'];
arr.forEach((item, index) => { 
    console.log(item);
    console.log(index);
})

若是我已經把匿名函數抽象出來,作成了一個公共的方法
(可能其餘地方也會用的到)
那麼,這個遍歷會是這樣的;函數

let arr = ['a', 'b', 'c'];
let myFunc = (item, index) => {
    console.log(item);
    console.log(index);
}
arr.forEach(myFunc);

注意:只要把方法對象傳給forEach就能夠嘍,參數什麼的,根本就不用關心;
若是這個方法在一個對象裏,那也沒什麼問題:this

let obj = {
    add(param, index) {
        console.log(param);
        console.log(index)
    }
}
let arr = ['a', 'b', 'c'];
arr.forEach(obj.add);

但,若是涉及到對象的this,那就要出問題了:code

let obj = {
    name: 'allen',
    add(param, index) {
        console.log(this.name);
        console.log(param);
        console.log(index)
    }
}
let arr = ['a', 'b', 'c'];
arr.forEach(obj.add);

輸出:對象

undefined
a
0
undefined
b
1
undefined
c
2

這是由於,add方法執行的時候,this對象指向的並非obj,而是forEach的對象,forEach的對象是全局對象golobal;
那想實現意圖怎麼辦呢?
最low的辦法就是給forEahc在套一個匿名函數it

arr.forEach((item, index) => obj.add(item, index));

其次是給forEach方法再多傳遞一個參數:console

arr.forEach(obj.add, obj);

這也不是什麼好主意,forEach你能夠多傳一個obj進去,其餘的相似forEach的方法,可不必定容許你多傳一個對象進去哦!
更好的辦法是:匿名函數

arr.forEach(obj.add.bind(obj));

bind建立了一個新函數,這個函數跟obj.add同樣,惟一不一樣的是,新函數把this綁定了obj
也就是說把add方法綁定給了接收者obj;
如今假設咱們的add方法,還須要另一個參數title,並且這是第一個參數:遍歷

add(title, param, index) {
        console.log(title);
        console.log(param);
        console.log(index)
}

那該如何是好呢?
你能夠直接在bind方法裏直接傳遞這個參數:方法

arr.forEach(obj.add.bind(obj, "mytitle"));

最終的代碼是:

let obj = {
    add(title, param, index) {
        console.log(title);
        console.log(param);
        console.log(index)
    }
}
let arr = ['a', 'b', 'c'];
arr.forEach(obj.add.bind(obj, "mytitle"));

輸出結果是:

mytitle
a
0
mytitle
b
1
mytitle
c
2

將函數與其參數的一個子集綁定的技術稱爲函數的柯里化; 比起顯式的封裝函數,這樣作更簡潔! (通常人也更不容易看懂你的代碼,哈哈哈!)  

相關文章
相關標籤/搜索