手写call()

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 输出'这是一台测试机器'
    *
    * */

猜你喜欢

转载自blog.csdn.net/Alive_tree/article/details/107857624