美文网首页
手写实现bind、call、apply

手写实现bind、call、apply

作者: chrisghb | 来源:发表于2019-08-14 11:36 被阅读0次
    var a = {
        value: 1
    }
    function getValue(name, age) {
        console.log(name)
        console.log(age)
        console.log(this.value)
    }
    getValue.myCall(a, 'yck', '24')
    getValue.myApply(a, ['yck', '24'])
    
    // 手动实现call
    Function.prototype.myCall = function (context) {
      // 兼容传入null的情况(context接收的是传入的第一个参数a)
      var context = context || window
      // getValue.myCall调用时,将this代表的原函数getValue添加到目标对象context属性fn上,即context.fn = getValue
      context.fn = this
      // arguments对象并不是一个真正的数组,而是一个类数组对象
      // 将 context 第二个开始的参数取出来=>('yck', '24')
      var args = [...arguments].slice(1)
      // 执行属性方法,相对于a.fn('yck', '24')
      var result = context.fn(...args)
      // 删除 fn
      delete context.fn
      return result
    }
    
    // 手动实现apply
    Function.prototype.myApply = function (context) {
      // 兼容传入null的情况(context接收的是传入的第一个参数a)
      var context = context || window
      // getValue.myCall调用时,将this代表的原函数getValue添加到目标对象context属性fn上,即context.fn = getValue
      context.fn = this
      var result
      // 如果存在第二个参数,就将第二个参数展开
      if (arguments[1]) {
        result = context.fn(...arguments[1])
      } else {
        result = context.fn()
      }
      // 删除 fn
      delete context.fn
      return result
    }
    

    bind 和其他两个方法作用也是一致的,只是该方法会返回一个函数。并且我们可以通过 bind 实现柯里化。
    函数柯里化:在一个函数中,首先填充几个参数,然后再返回一个新的函数的技术,称为函数的柯里化。通常可用于在不侵入函数的前提下,为函数 预置通用参数,供多次重复调用。

    var a = {
      name : "Cherry",
      fn : function (x,y) {
        console.log( x + y)
      }
    }
    
    var b = a.fn
    var c = b.myBind (a,1) 
    c(5) // 6
    
    // 手动实现bind
    Function.prototype.myBind = function (context) {
      if (typeof this !== 'function') {
        throw new TypeError('Error')
      }
      var _this = this // this代表a.fn 
      var args = [...arguments].slice(1) // 参数1
      // 返回一个函数
      return function F() {
        // 如果this是F的实例
        if (this instanceof F) {
          return new _this(...args, ...arguments) //参数 1和5合并
        }
        return _this.apply(context, args.concat(...arguments))
      }
    }
    

    相关文章

      网友评论

          本文标题:手写实现bind、call、apply

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