之所以要寫這篇,是因為曾經面試被要求在白紙上手寫bind實現
結果跟程式碼一樣清晰明確,一陣懵逼,沒寫出來!
下面,擼起袖子就是幹!~
把call、apply、bind一條龍都整一遍!~~
call
定義與使用
Function.prototype.call(): developer.mozilla.org/zh-CN/docs/…
// Function.prototype.call()樣例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 接受的是一個引數列表;方法立即執行
fun.call(_this, 1, 2)
// 輸出:
YIYING
3
手寫實現
/** * 自定義call實現 * @param context 上下文this物件 * @param args 動態引數 */
Function.prototype.ownCall = function(context, ...args) {
context = (typeof context === 'object' ? context : window)
// 防止覆蓋掉原有屬性
const key = Symbol()
// 這裡的this為需要執行的方法
context[key] = this
// 方法執行
const result = context[key](...args)
delete context[key]
return result
}
// 驗證樣例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 接受的是一個引數列表;方法立即執行
fun.ownCall(_this, 1, 2)
// 輸出:
YIYING
3
apply
定義與使用
Function.prototype.apply(): developer.mozilla.org/zh-CN/docs/…
// Function.prototype.apply()樣例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 引數為陣列;方法立即執行
fun.apply(_this, [1, 2])
// 輸出:
YIYING
3
手寫實現
/** * 自定義Apply實現 * @param context 上下文this物件 * @param args 引數陣列 */
Function.prototype.ownApply = function(context, args) {
context = (typeof context === 'object' ? context : window)
// 防止覆蓋掉原有屬性
const key = Symbol()
// 這裡的this為需要執行的方法
context[key] = this
// 方法執行
const result = context[key](...args)
delete context[key]
return result
}
// 驗證樣例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 引數為陣列;方法立即執行
fun.ownApply(_this, [1, 2])
// 輸出:
YIYING
3
bind
定義與使用
Function.prototype.bind()
: developer.mozilla.org/zh-CN/docs/…
// Function.prototype.bind()樣例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 只變更fun中的this指向,返回新function物件
const newFun = fun.bind(_this)
newFun(1, 2)
// 輸出:
YIYING
3
參考 前端進階面試題詳細解答
手寫實現
/** * 自定義bind實現 * @param context 上下文 * @returns {Function} */
Function.prototype.ownBind = function(context) {
context = (typeof context === 'object' ? context : window)
return (...args)=>{
this.call(context, ...args)
}
}
// 驗證樣例
function fun(arg1, arg2) {
console.log(this.name)
console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 只變更fun中的this指向,返回新function物件
const newFun = fun.ownBind(_this)
newFun(1, 2)
// 輸出:
YIYING
3