Handwriting call, apply and bind function

First, from the following points to consider how to implement these functions:

  • The first parameter is not passed, then the default context for the window;
  • Changed this point, so that the new object can perform this function, and can accept parameters.

So call us first to achieve

Function.prototype.myCall = function(context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  context = context || window
  context.fn = this
  const args = [...arguments].slice(1)
  const result = context.fn(...args)
  delete context.fn
  return result
}

analysis:

  • First, context is optional, if you do not pass, then the default context for the window;
  • Next, create a fn property to the context, and set the value as a function of the need to call;
  • Because the call number of parameters can be passed as a parameter to a function call, it needs to be stripped out parameters, and then call the function on the function and object deletion (because the object itself is not the function, but in the scope of delivery called, make a temporary property).
    The idea is to achieve the above call, apply implementation is similar, except that the processing parameters, it is not one of the analysis of ideas.
Function.prototype.myApply = function(context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  context = context || window
  context.fn = this
  let result
  // 处理参数和 call 有区别
  if (arguments[1]) {
    result = context.fn(...arguments[1])
  } else {
    result = context.fn()
  }
  delete context.fn
  return result
}

bind implementation compared to other two functions are slightly more complicated, because the need to return a bind function, you need to determine the number of border issues, the following are bind implementation:

Function.prototype.myBind = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  const _this = this
  const args = [...arguments].slice(1)
  // 返回一个函数
  return function F() {
    // 因为返回了一个函数,我们可以 new F(),所以需要判断
    if (this instanceof F) {
      return new _this(...args, ...arguments)
    }
    return _this.apply(context, args.concat(...arguments))
  }
}

analysis:

  • And the first steps before implementation almost, not go into details.
  • bind returns a function, a function is invoked in two ways, one is called directly, one is the new way through, the way we first is called directly;
    • For direct calls, here we chose to apply the ways, but parameters need to pay attention to the following: bind because such code can achieve similar f.bind (obj, 1) (2), so we need to both sides of the argument splicing up, so there is this realization args.concat (... arguments);
    • Finally, it is through new ways, in this case, it will not be any change in this way, so for this we need to ignore the return function of this.

Another implementation Reference

UFI
Published 16 original articles · won praise 2 · Views 1190

Guess you like

Origin blog.csdn.net/qq_39075021/article/details/104331887