资讯专栏INFORMATION COLUMN

【build your own xxx】实现你自己的call和apply

qpal / 1767人阅读

摘要:新开一个坑,起名为,自己造一些小轮子。之前貌似在知乎上看到一个问题是说如何使用实现它原生的和方法,今天我来实现一番。但是,这样等于说只给传了一个数组参数,并不能达到目的。同理来实现参考资料深入之和的模拟实现

新开一个坑,起名为【build your xxx】,自己造一些小轮子。
工作中不要重复造轮子,但是以学习的目的去造轮子却意义重大。
之前貌似在知乎上看到一个问题是说如何使用JavaScript实现它原生的call和apply方法,今天我来实现一番。

call

首先看看call是干什么的,从MDN上扒一张图:

举个例子

function showName(gender, age){
    console.log(this.name, " ", gender, " ", age)
}
var obj = {
    name: "亚古"
}
showName.call(obj, "female", 22)// 亚古   female   22

梳理思路
可以看出来Func.call(obj, arg1, arg2...)实现了这么几件事:

以obj.Func的方式调用

把参数arg1, arg2 ...传递给Func

不对obj和Func造成副作用

实现

Function.prototype.Zcall = function (othis) {
    othis.fn = this;
    othis.fn();
}
showName.Zcall(obj) // 亚古   undefined   undefined

第一个步骤已经实现了,但是很明显的是这样子会对传入的othis造成副作用,即给othis对象无缘无故添加了一个方法,所以:

Function.prototype.Zcall = function (othis) {
    othis.fn = this;
    othis.fn();
    delete othis.fn;
}

副作用已经消除了,接下来就是参数的问题,这里有个问题是参数个数是不定的,貌似可以使用一个数组来arr保存住arguments里面的参数,然后再执行othis.fn(arr)。但是,这样等于说只给fn传了一个数组参数,并不能达到目的。此时问题转化为我们如何实现像 othis.fn(arguments[0], arguments[1], arguments[2] ...) 这样的语句呢?
此时可以想起一个不怎么常用的方法eval

简单的说就是可以把字符串解析为JavaScript语句来执行。
借助eval,改写Zcall方法:

Function.prototype.Zcall = function (othis) {
    othis.fn = this;
    let args = [];
    for(let i = 1, len = arguments.length;i < len;i++) {
        args.push("arguments[" + i + "]");
    }

    // othis.fn();
    eval("othis.fn(" + args + ")");
    delete othis.fn;
}

其实就是用args把arguments用字符串的方式保存住,然后在eval方法中再把字符串重新解析为语句。

apply

同理来实现apply:

Function.prototype.Zapply = function (othis) {
    othis.fn = this;
    let argsArr = arguments[1];
    if (!arguments[1]) {
        let args = [];
        for(let i = 0, len = arguments[1].length;i < len;i++) {
            args.push("arguments[1][" + i + "]");
        }

        eval("othis.fn(" + args + ")");
    }else{
        othis.fn();
    }
    
    delete othis.fn;
}

参考资料:
MDN-eval
MDN-apply
JavaScript深入之call和apply的模拟实现

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107898.html

相关文章

  • build your own xxx实现自己bind函数

    今天来实现JavaScript的bind函数。首先看MDN的bind函数描述: 从上面可以看出来,var A = B.bind(this)函数其实干了这几件事情: 返回一个函数,且这个函数后面运行时的this就是bind(this)传入的this 接收参数,这些参数(如果有的话)作为bind()的第二个参数跟在this(或其他对象)后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定...

    dantezhao 评论0 收藏0

发表评论

0条评论

qpal

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<