美文网首页
call,bind,apply 方法的原理解析和原生JS模拟实现

call,bind,apply 方法的原理解析和原生JS模拟实现

作者: 小鱼旋子 | 来源:发表于2019-06-21 23:45 被阅读0次

call 方法内部实现

  1. 将这个函数设为指定对象的属性
  2. 传参后执行这个对象的方法
  3. 删除这个函数
  4. 返回对象的函数执行结果

模拟实现

Function.prototype.call2 = function(opp) { 
     opp.fn = this; 
     let args = [...arguments].slice(1); 
     let result = opp.fn(...args); 
     delete opp.fn;
     return result; 
}

apply 方法内部实现

思路类似手写call函数的思路如下,
不同:传参时只是第二个参数有,且为数组;不像call,除了第一个参数都是需要的参数
1.将这个函数设为指定对象的属性
2.传参后执行这个对象的方法

  1. 删除这个函数
    4.返回对象的函数执行结果

模拟实现

Function.prototype.apply2 = function(opp) {
     opp.fn = this;
     let result;
     if(auguments[1]) {  //判断是否有第二个参数,即是否有传入调用函数的参数
       result = opp.fn(…arguments[1])
  } else {
     result = opp.fn()
  }
  delete opp.fn;
  return result;
}

bind 方法内部实现

  1. 返回一个函数,绑定this,传递预置参数
  2. bind返回的函数可以作为构造函数使用
    需注意:通过new实例化后 this 指向的是创建出的新对象,还注意对原型链的影响

模拟实现

Funcrion.prototype.bind2 = function(opp) {
  let fn = this;
  let args = [...arguments].slice(1);
  let resFn = function() {
    fn.apply(this.instanceof fn ? this : opp, args.concat([...arguments]) )
     // 检测 New: 如果当前函数的this指向的是构造函数中的this 则判定为new 操作
  }
  //为了完成 new操作, 还需要进行原型链接
  // 这里创建了一个空函数来做中间人,承接原函数(此时为构造函数了)的原型 给 返回的绑定函数(resFn))
  function Tmp() {}
  Tmp.prototype = fn.prototype;
  resFn.prototype = new Tmp(); // 修改返回函数的prototype为 绑定函数的prototype,这样的话通过new创建的实例就可以继承这个绑定函数(此为构造函数)中的属性;【原型链式继承】
  //但是直接赋值的话当修改返回函数的prototype时绑定函数的prototype也不会被影响,所以创建了一个中间函数
   
  return resFn;
}

相关文章

网友评论

      本文标题:call,bind,apply 方法的原理解析和原生JS模拟实现

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