bind() 方法,會建立一個新函式。該函式被呼叫時,會將 this 關鍵字設為給定的參數,並在呼叫時,帶有提供之前,給定順序的參數。
polyfill
var slice = Array.prototype.slice
function bind(){
var that = arguments[0]
var thatArgs = slice.call(arguments, 1)
var fn = this
if(typof fn !== function){
throw new Error('bind 必須調用在函數上')
}
return function(){
var funcArgs = slice.call(arguments,0)
return fn.apply(that, thatArgs.concat(funcArgs))
}
}
我們來一次拆分函數:
我們先將Array.slice的方法存到變數slice中,方便之後要處理arguments的值。
接著將arguments的第一個參數,也就是傳入要修改的this值存到that變數中。
將剩餘的參數存至thatArgs中,再將當前this存到fn變數中。
這個fn就是我們bind的函數,所以若bind的不是函數則會拋出錯誤。
因為bind會返回一個函數,所以我們這邊也會回傳函數。
函數中使用funcArgs用來儲存返回的函數中所傳的參數。
接著使用apply將傳入的this以及將全部參數加入綁定到fn函數中。
但是這個bind還有一個問題是當我們使用new時會出現錯誤。
var slice = Array.prototype.slice
function bind(){
var that = arguments[0]
var thatArgs = slice.call(arguments, 1)
var fn = this
if(typof fn !== function){
throw new Error('bind 必須調用在函數上')
}
function resultsFn(){
var funcArgs = slice.call(arguments,0)
return fn.apply(
resultsFn.prototype.isPrototypeOf(this) ? this : that,
thatArgs.concat(funcArgs)
)
}
resultsFn.prototype = fn.prototype
return resultsFn
}
在開發時多少有使用過bind這個方法,但是卻沒有想過他是怎麼實現的,今天就要來研究一下。
先來看mdn 的定義:
polyfill
我們來一次拆分函數:
接著使用apply將傳入的this以及將全部參數加入綁定到fn函數中。
但是這個bind還有一個問題是當我們使用new時會出現錯誤。
上面程式碼就使我們支援new 方法呼叫bind