实现 call apply

67 阅读1分钟

call/bind

/*
 * call
 */
// es6
Function.prototype.myCall = function (context) {
  if (context === null || context === undefined) {
    context = window
  } else {
    context = Object(context)
  }

  const args = [...arguments].slice(1)
  // context.fn = this;
  // const result = context.fn(...args)
  // delete context.fn;
  
  // 或者
  const fn = SymBol();
  context[fn] = this;
  const result = context[fn](...arr);
  delete context[fn];

  return result
}

// es5
Function.prototype.myCall2 = function (context) {
  var context = context || window;
  context.fn = this;

  var args = [];
  for(var i = 1, len = arguments.length; i < len; i++) {
    args.push('arguments[' + i + ']');
  }

  var result = eval('context.fn(' + args +')');

  delete context.fn
  return result;
}

/*
 * apply
 */
// es6
Function.prototype.myApply = function (context, arr) {
  if (context === null || context === undefined) {
    context = window
  } else {
    context = Object(context)
  }

  // context.fn = this;
  // const result = context.fn(...arr)
  // delete context.fn;
  
  // 或者
  const fn = SymBol();
  context[fn] = this;
  const result = context[fn](...arr);
  delete context[fn];
  return result
}

// es5
Function.prototype.myApply2 = function (context, arr) {
  var context = Object(context) || window;
  context.fn = this;

  var result;
  if (!arr) {
    result = context.fn();
  }
  else {
    var args = [];
    for (var i = 0, len = arr.length; i < len; i++) {
      args.push('arr[' + i + ']');
    }
    result = eval('context.fn(' + args + ')')
  }

  delete context.fn
  return result;
}