bind、call、apply 區別
call
和apply
都是爲了解決改變this
的指向。作用都是相同的,只是傳參的方式不同。- 除了第一個參數外,
call
可以接收一個參數列表,apply
只接受一個參數數組
let a = {
value: 1
}
function getValue(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])
bind
和其他兩個方法作用也是一致的,只是該方法會返回一個函數。並且我們可以通過 bind
實現柯里化
如何實現一個 bind 函數
對於實現以下幾個函數,可以從幾個方面思考
- 不傳入第一個參數,那麼默認爲
window
- 改變了
this
指向,讓新的對象可以執行該函數。那麼思路是否可以變成給新的對象添加一個函數,然後在執行完以後刪除?
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
var _this = this
var args = [...arguments].slice(1)
// 返回一個函數
return function F() {
// 因爲返回了一個函數,我們可以 new F(),所以需要判斷
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}
如何實現一個 call 函數
Function.prototype.myCall = function (context) {
var context = context || window
// 給 context 添加一個屬性
// getValue.call(a, 'yck', '24') => a.fn = getValue
context.fn = this
// 將 context 後面的參數取出來
var args = [...arguments].slice(1)
// getValue.call(a, 'yck', '24') => a.fn('yck', '24')
var result = context.fn(...args)
// 刪除 fn
delete context.fn
return result
}
如何實現一個 apply 函數
Function.prototype.myApply = function (context) {
var context = context || window
context.fn = this
var result
// 需要判斷是否存儲第二個參數
// 如果存在,就將第二個參數展開
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}
個人博客地址:大家可以看看