手寫一個bind函數(shù)是面試中一個常見的面試題,由于bind函數(shù)是es5之后才有的,有些低版本的游覽器可能不支持截珍,有時候在開發(fā)中常常需要手寫封裝一個bind()函數(shù)锚扎。
那怎么實現(xiàn)bind()函數(shù)的封裝呢吞瞪?
這里就不得不提函數(shù)柯里化,那什么是函數(shù)柯里化呢工秩?請看百度百科的解釋:
在計算機科學(xué)中尸饺,柯里化(Currying)是把接受多個參數(shù)的函數(shù)變換成接受一個單一參數(shù)(最初函數(shù)的第一個參數(shù))的函數(shù)进统,并且返回接受余下的參數(shù)且返回結(jié)果的新函數(shù)的技術(shù)。這個技術(shù)由 Christopher Strachey 以邏輯學(xué)家 Haskell Curry 命名的浪听,盡管它是 Moses Schnfinkel 和 Gottlob Frege 發(fā)明的螟碎。
這不是針對js語言,大多數(shù)語言都支持該特性
請看一個簡單的栗子
function add(x+y){
let result=x+y //我們平時寫一個兩個數(shù)相加的函數(shù)是這樣寫的迹栓,
return result
}
console.log(add(3,7) //10
如果現(xiàn)在有一個需求掉分,add函數(shù)調(diào)用一次只能加一個數(shù),需要調(diào)用兩次才能出結(jié)果克伊,這里就需要用到函數(shù)柯里化 /想要了解函數(shù)柯里化最好能先對閉包有一個深入的了解/
function add(x){
let result=x
return function(y){ //這里返回一個函數(shù)
return result=result+y
}
}
let add1=add(3)(7)
console.log(add1) //10
可以看出函數(shù)柯里化就是是利用了閉包的特性酥郭,
所以以后在看代碼中看到以下的調(diào)用方式就不足為怪了
add(2)(3)(9)
add(2,3,5)(4,6)(3,4)
好了,現(xiàn)在就回到標題,那么很顯然可以利用函數(shù)柯里化手寫bind()函數(shù)
思路:1.使用es6的rest參數(shù)獲取傳入的參數(shù)愿吹,合并兩次傳入的參數(shù)
2.使用函數(shù)柯里化(閉包)不从,和原生apply方法
/*
param obj 綁定的對象
*/
Object.prototype.myBind=function(obj,...params){ //使用es6 rest參數(shù),
let paramOne=params //也可以使用es5中的argurments獲取傳入的參數(shù)
let self=this
return function(...params){
let paramsTwo=params
let mergeParams=[...paramOne,...paramsTwo] //合并兩次傳入的參數(shù)
console.log(mergeParams)
return self.apply(obj,mergeParams)
}
}
let obj1={
sayHello:function(str1,str2){
return str1+ str2+ this.name
}
}
let obj2={
name:"帥朗朗"
}
let result=obj1.sayHello.myBind(obj2,'hello')('world')
console.log(result) //helloworld帥朗朗
由此可見函數(shù)柯里化的主要作用和特點就是參數(shù)復(fù)用犁跪、提前返回和延遲執(zhí)行椿息。