手撸 JS apply 和 call 实现

669 阅读1分钟

call实现:

apply 和 call 主要就是传参的区别。这里就不多说了,直接看代码。

  //call 实现
  Function.prototype.myCall = function(context) {
       
      context.fn = this
       
      var args = [...arguments].slice(1)
       
      var result = context.fn(...args)
       
      delete context.fn
       
      return result
  }
  
  //调用
  var obj = {
       name: 'xiaoming'
   }
   
   function foo(sex, age) {
       console.log(sex + ' ' + this.name + ' ' + age);
   }
   foo.myCall(obj, 'boy', '25');// boy xiaoming 25

实现原理:

其实就是把fn放在obj下面执行(后面得把obj.fn从obj上删除了,保持obj的孑然之身嘛!),context.fn = this,obj这个对象就不止name属性了吧,多了fn属性,就是函数foo。然后context.fn()执行的时候,由于fn是context也就是obj调用的,那么在foo内部执行的时候, this.name就会找到obj的name,变相达成了实现this指向的更改或者说是其他对象的劫持。

apply实现:

Function.prototype.myApply = function(context) {
 
    var context = context || window
 
    context.fn = this
 
    var result;
 
    // 需要判断是否存储第二个参数,如果存在,就将第二个参数展开
 
    if(arguments[1]) {
        result = context.fn(...arguments[1])
    } else{
        result = context.fn()
    }
 
    delete context.fn
 
    return result
}
传送门:bind实现原理