本文內容
1、比較call、apply、bind的相同點和不同點
2、手寫簡單的call、apply、bind
比較call、apply和bind
相同點
- 都是用於改變
this
指向; - 傳遞參數時,第一個參數是需要改變成的
this
指向。
不同點
call
傳遞參數時,從第二個參數開始依次進行傳遞;apply
傳遞參數時,第二個參數是一個數組,數組裏面的每一項依次是向函數傳遞的參數;bind
不會立即執行函數,而是返回一個改變了this
指向的新函數,使用bind
時可以直接傳遞參數(優先級高),也可以在新函數調用時傳遞參數。
手寫bind
// 封裝 call
Function.prototype.myCall = function (context) {
var context = Object(context) || window;
context.fn = this;
const args = [...arguments].slice(1);
let result = context.fn(...args);
delete context.fn;
return result;
}
// 封裝 apply
Function.prototype.myApply = function (context, args) {
var context = Object(context) || window;
context.fn = this;
let result = !args ? context.fn() : context.fn(...args);
delete context.fn;
return result;
}
// 封裝 bind
Function.prototype.myBind = function (context) {
if (typeof this !== "function") {
throw new Error("不是一個函數");
}
const self = this;
let arg1 = [...arguments].slice(1);
const bindFn = function () {
const arg2 = [...arguments];
return self.myApply(context, arg1.concat(arg2));
}
return bindFn;
}
function pn(a, b, c, d) {
console.log(this.value, a, b, c, d)
}
const obj = { value: 100 };
pn.myBind(obj, 10, 20)(30, 40);
// 100 10 20 30 40