JavaScript中call方法的手动实现,与多个call连用引发的思考.

今天在学习js的时候想到个有趣的问题, 自己实现一个call方法?. 
改变一个函数的this指向这种事听起来真的很原生态.

第一步:
  知己知彼,先从这个方法本身下手, 看看他到底有什么神通.
  // 1:定义个举例函数;
  function fn1(n){
   console.log('我是fn1',n,this)
  }
  function fn2(n){
   console.log('我是fn2',n,this)
  }
  let call = fn1.call
  
  // 2: 打印一下 他的call方法
  // 既然是function, 本身也就肯定也有call方法了,继续
  console.log(call)            // ƒ call() { [native code] }  
  console.log(call.call)       // ƒ call() { [native code] }
  console.log(call.call.call)  // ƒ call() { [native code] }
  
  // 3: 实际试试输出
    fn1.call.call(fn2,1)            // 我是fn2  undefined  Number {1}
    fn1.call.call.call(fn2,1)       // 我是fn2  undefined  Number {1}
    fn1.call.call.call.call(fn2,1)  // 我是fn2  undefined  Number {1}
    
  // 4: 看到这个结果的时候我蒙了, 这怎么执行fn2了, n是未定义, this指向了1
  //    感觉整体往后移了一位, ?呆滞.
  
  第二步: 查资料,逐步实现.
    真的很好奇,难道里面有什么判断规则?, 我找了几篇文章, 也没找到答案, 最后在曾经看过的视频里面找到了答案.
    // 1: 当然是定义在函数上了
    Function.prototype.myCall = function(context) {
     // 2: 如果传进来的第一个参数为空,就把它当做window, 所以我们平时想要指向window的时候才会穿个undefined,''之类的, Object()一下这个数, 是为了让他本身可以有对象的特性.
       context = context ? Object(context) : window;
     // 3: 这个this就是调用当前call方法的'.'前面的对象
     // 相当于模拟了一个对象
     // context === fn2 === { fn:fn1 } // 所以里面的fn1的this指向也就是父级fn2了.
      context.fn = this;
     // 4: 参数要处理一下, 以便传入到函数里面.
    let as = [];
       // 要从1开始, 因为第一个要作为this
    for (let i = 1; i < arguments.length; i++) {
      as.push(arguments[i]);
     }
    // 5: 执行context的fn方法, 也就是执行, 调用call的函数
    //    数组的加法, 比如 [1,2,3]+'' 结果是 1,2,3 这样就符合参数的样子了
    let r = eval('context.fn(' + as + ')');
    
    // 6: 做完这些, 当然要好好善后啦
    delete context.fn;
    return r
    };
    
    // 实验结果
    fn1.call(fn2,1) // 我是fn1 1 fn2
    
    
    第三步: 让我们来理解一下那个多次调用的问题.
    
    首先 :不管写几个call 都是call方法本身去调了一下call(fn2), 执行的时候,也就是相当于, 把call它的this指向变成 fn2, 并执行call这个方法,  而call这个方法一执行就会默再去认执行一下相当于fn2.call(后面的参数),因为fn2是他的this, 就相当于把后面的 1 当做要指定的this传进去, 也就造成了往后窜了一位.
    
    第四步: 总结
     
     不管写多少个call, 执行第一个参数, 第二个参数为第一个参数this的指向, 第三个参数开始是传参...哈哈挺有意思!
  
  
  
  
  
  
  
  
  
  
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值