相同點(diǎn):call apply bind都是為了改變函數(shù)的this指向
不同點(diǎn):
1)call 參數(shù)依次傳入
2)apply 參數(shù)以數(shù)組的方式傳入
3)bind 是一個(gè)方法,需要用()才能執(zhí)行,兩種傳參方法都可以
obj.myFun.call(db,'成都','上海'); // 德瑪 年齡 99 來自 成都去往上海
obj.myFun.apply(db,['成都','上海']); // 德瑪 年齡 99 來自 成都去往上海
obj.myFun.bind(db,'成都','上海')(); // 德瑪 年齡 99 來自 成都去往上海
obj.myFun.bind(db,['成都','上海'])(); // 德瑪 年齡 99 來自 成都, 上海去往
手寫實(shí)現(xiàn)#
call
Function.prototype.myCall = function(context) {
if(typeof this !="function"){
throw new TypeError()
}
//如果沒有傳參,綁定window
context=context||window
// 改變this的指向
context.fn=this
//獲得參數(shù)
const args=[...arguments].slice(1)
//執(zhí)行這個(gè)方法
const result=context.fn(...args)
//刪除我們聲明的fn屬性
delete context.fn
return result
}
apply
Function.prototype.myApply = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
// 處理參數(shù)和 call 有區(qū)別
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
bind
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
const _this = this
const args = [...arguments].slice(1)
// 返回?個(gè)函數(shù)
return function F() {
// 因?yàn)榉祷亓?個(gè)函數(shù),我們可以 new F(),所以需要判斷
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}
f.say.myCall(fn,"call","y")//namecally
f.say.myApply(fn,["apply","y"])//nameapplyy
f.say.myBind(fn,"bind","y")()//fnbindy