call()为this函数/方法提供新的值,使用call(),您可以编写一次方法,然后在另一个对象中继承该方法 ,而不必为新对象重写该方法。
注意:虽然apply()与call()方法一致,但是基本区别call()接受参数列表,而apply()接受参数数组。
语法
function.call(thisArg, arg1, arg2, ...)
call()的原理比较简单,由于函数的this指向它的直接调用者,我们变更调用者即可完成This指向的变更。
先看个例子
//定义一个方法
function foo() {
console.log(this.desc);
}
//定义一个对象
const device ={
desc:'这是一台测试机器'
};
//对象调用方法
device.foo = foo; //给device对象赋foo方法
device.foo(); //这是一台测试机器
基于以上原理,我们需要的是写一个函数,能够改变This指向的函数。
所以就有;
简单写法
Function.prototype.mycall=function(thisArg, ...args) {
thisArg.fn = this; //this指向调用call的对象,即我们要改变this指向的函数
return thisArg.fn(...args);
};
再优化一下
Function.prototype.mycall = function (thisArg, ...args) {
if (typeof this !== 'function') {
throw new TypeError(`${this} is not a function`)
}
thisArg = thisArg || window;
thisArg.fn = this;
const result = thisArg.fn(...args) //执行当前函数
delete thisArg.fn;
return result;
};
测试一下
foo.mycall(device); //这是一台测试机器
测试思路
/*
* 1、mycall执行传入的device参数
* 2、先判断调用mycall的对象是不是个函数,如果不是则报错,这里是foo调用mycall
* 3、device.fn = foo(); device有了foo方法
* 4、device.foo()执行了 并用result接收
* 5、返回result 输出'这是一台测试机器'
*
* */