美文网首页
【js基础修炼之路】- 手把手教你实现call和apply

【js基础修炼之路】- 手把手教你实现call和apply

作者: 张举欣 | 来源:发表于2019-01-29 18:00 被阅读101次

    call 和apply一直在项目中使用,但是一直不知道是怎么实现,今天实现了一下

    call和apply的用法

     var obj = {
         value: 1
     }
    
     function bar(name, age) {
         return {
             value: this.value,
             name: name,
             age: age
         }
     }
     console.log(bar.apply(obj, ['zjx', 21]));
     console.log(bar.call(obj, 'zjx', 21));
    //{ value: 1, name: 'zjx', age: 21 }
    

    call和apply的作用就是绑定this并立即执行函数,他们的区别就是apply传给函数的参数是数组形式,call不需要数组,直接写,相信大家看完代码就可以理解,在这里不过多赘述。

    手写call

     var obj = {
         value: 1
     }
    
     function bar(name, age) {
         return {
             value: this.value,
             name: name,
             age: age
         }
     }
    

    想让上面代码的bar函数的this指向obj,下面的代码是不是可以实现呢

     var obj = {
         value: 1,
         bar: function(name, age) {
             return {
                 value: this.value,
                 name: name,
                 age: age
             }
         }
     }
    
    

    相信看了代码你会明白,那么我们就按照这个方法去一步步实现:
    给obj添加bar方法,然后执行方法,然后把添加的方法删除

      //如果call的第一个参数是null,那么this就指向window
     Function.prototype.call2 = function(context = window) {
         //添加函数(this:调用call的函数)
         context.fn = this;
         var args = [];
         // 取出第二个到最后一个参数
         for (var i = 1, len = arguments.length; i < len; i++) {
             args.push('arguments[' + i + ']');
         }
          //args : [ 'arguments[1]', 'arguments[2]' ]
         //执行函数,res是函数的返回值
         var res = eval('context.fn(' + args + ')');
         // args是一个数组,但是在eval里面会转成字符串也就是 'arguments[1]', 'arguments[2]' 
        //也就对应着下面的zjx和21两个参数
        //删除添加的函数
         delete context.fn;
        //返回函数返回的结果
         return res;
     }
     var obj = {
         value: 1
     }
    
     function bar(name, age) {
         return {
             value: this.value,
             name: name,
             age: age
         }
     }
     console.log(bar.call2(obj, 'zjx', 21));
    

    手写apply

    apply的实现思路和call类似,相信你看完代码就会明白的,下面直接给出代码

     Function.prototype.apply2 = function(context, arr) {
         var context = Object(context) || window;
         console.log(context, 'context');
         context.fn = this;
         var result;
         if (!arr) {
             result = context.fn();
         } else {
             var args = [];
             for (var i = 0, len = arr.length; i < len; i++) {
                 args.push('arr[' + i + ']');
             }
             result = eval('context.fn(' + args + ')')
         }
         delete context.fn
         return result;
     }
     console.log(bar.apply2(obj, ['zjx', 21]));
    

    相关文章

      网友评论

          本文标题:【js基础修炼之路】- 手把手教你实现call和apply

          本文链接:https://www.haomeiwen.com/subject/sfaxsqtx.html