js高级进阶——手动实现call()函数

// 首先看下原生的js的call()
var obj = {
  name: 'Nicholas S.Zakas',
  age: 41,
  from: 'America',
  getName: function (prefix) {
    // console.log(prefix + this.name)
    return prefix + this.name
  }
}

var obj2 = {
  name: 'Evan You',
  age: '35',
  from: 'China'
}

console.log(obj.getName.call(obj2, 'hello, everyone, i am '))
// hello, everyone, i am Evan You

// call()作了什么?
// 一、将调用call的函数的this指向call函数的第一个参数
// 二、将call()第一个参数后的参数做为调用call函数的形参
Function.prototype._call = function (context) {
  var result
  var args = [].slice.apply(arguments, [1])
  context.fn = this
  result = context.fn(...args)
  delete context.fn
  return result
}

// 不使用call函数的实现
Function.prototype._newCall = function (context) {
  var args = []
  var result
  for (var i = 1; i < arguments.length; i++) {
    args.push('arguments[' + i + ']')
  }
  context.fn = this
  result = eval('context.fn(' + args + ')')
  delete context.fn
  return result
}

console.log(obj.getName._newCall(obj2, 'hello, everyone, i am '));
// hello, everyone, i am Evan You

// ECMAScript6 的实现
Function.prototype._es6Call = function (context, ...args) {
  var result
  context.fn = this
  result = context.fn(...args)
  delete context.fn
  return result
}

console.log(obj.getName._es6Call(obj2, 'hello, everyone, i am '));
 // hello, everyone, i am Evan You

 

2020.05.15 修正函数调用call会有返回值javascript