call()和apply()差不多,要利用好函数的谁调用它,它的this就指向谁的特点。
Function.prototype.call()的实现
//实现
Function.prototype.myCall = function (obj, ...args) {
obj = obj ?? window;
obj = (obj instanceof Object) ? obj : Object(obj);
const _this = this;
const fnName = _this.name;
obj[fnName] = _this;
const result = obj[fnName](...args);
delete obj[_this.name];
return result;
}
//测试
const obj = {
age: '123456'
}
function fn() {
console.log(this)
console.log(Array.from(arguments));
}
fn.myCall(1, 1, 2, 3);
fn.myCall(obj, 1, 2, 3);
fn.myCall(null, 1, 2, 3);
Function.prototype.apply()的实现
//实现
Function.prototype.myApply = function (obj, arg) {
obj = obj ?? window;
obj = (obj instanceof Object) ? obj : Object(obj);
const _this = this;
const fnName = _this.name;
obj[fnName] = _this;
const result = obj[fnName](...arg);
delete obj[_this.name];
return result;
}
//测试
const obj = {
age: '123456'
}
function fn() {
console.log(this.age)
console.log(Array.from(arguments));
}
fn.myApply(1, [1, 2, 3]);
fn.myApply(obj, [1, 2, 3]);
fn.myApply(null, [1, 2, 3]);
bind()的实现有点差异,它的思想是返回一个新的函数,在新的函数内部再对原函数进行this绑定的调用
Function.prototype.bind()的实现
//实现
Function.prototype.myBind = function (obj, ...args) {
obj = obj ?? window;
obj = (obj instanceof Object) ? obj : Object(obj);
const _this = this;
const inner = function (...anotherArgs) {
args.push(...anotherArgs);
return _this.call(obj, ...args);
}
return inner;
}
function Fn() {
console.log(this);
console.log(Array.from(arguments));
}
const obj = {
name: 'arthur',
age: 15
}
const a = Fn.myBind(obj, 6, 7);
const b = Fn.myBind(1, 6, 7);
const c = Fn.myBind(null, 6, 7);
a(1, 2);
b(1, 2);
c(1, 2);