10. call和apply的模拟实现 - cw84973570/Learning-notes GitHub Wiki

https://github.com/mqyqingfeng/Blog/issues/11

思路:将要执行的函数添加到对象的属性,执行完毕后删除该属性。若要传递参数则用eval函数实现。

Function.prototype.call2 = function(context) {
  context = context || window
  var args = []
  for(var i = 1, len = arguments.length; i < len; i++) { // 获取参数
    args.push('arguments[' + i + ']')
  }
  context.fn = this // 获取调用的函数,fn.call2(obj),this就是fn
  var result = eval('context.fn(' + args + ')') // 通过eval解析,执行函数并获取结果
  context.fn()
  delete context.fn
  return result // 返回结果
}
var foo = {
  value: 1
}
function bar(name) {
  console.log(this.value)
  console.log(name)
}
bar.call2(foo, 'bar')
Function.prototype.apply2 = function(context, arr) {
  context = context || window
  // content = 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
}
var foo = {
  value: 1
}
function bar(name, age) {
  console.log(this.value)
  console.log(name)
  console.log(age)
}
bar.apply2(foo, ['bar', '18'])