本文内容
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