javascript中call()方法的本地实现

时间:2019-04-29 16:53:54

标签: javascript

我试图在javascript中执行call方法的本地实现。在这里,我们需要处理在调用函数和其他参数中传递的对象。我使用eval()方法处理其他参数。有没有有效的方法来执行本机call()函数实现。这是我的代码

var name = {
    name: "JavaScript", 
  version: "6",
}   

function printName(location, district){
    alert(this.name + ", " + this.version + ", " + location + ", " + district);
}

Function.prototype.myCall = function(...args){
  var param = args.slice(1),
      paramLength = param.length, 
      paramString = "JSONarg.myFun(";
  for(var i = 1; i <= paramLength; i++){
    paramString += "args["+i+"],";
  }
  paramString += ")";

  if(typeof this != 'function'){
    throw new Error(this + " is not a Function");
  }

  var JSONarg =  {
    ...args[0],
    myFun: this
  }
  return eval(paramString);
}

printName.myCall(name, "Chrome", "browser");

2 个答案:

答案 0 :(得分:1)

没有通话。

Function.prototype.myCall = function(context, ...args){
    this.apply(context, args)
}

但是我没有理由

答案 1 :(得分:0)

您的 call 方法实现似乎是 ES3 版本,因为您创建了一个 params 列表字符串并使用 eval 来执行该函数。但是你也在这里使用了rest params,证明浏览器支持ES6。所以我们可以使用扩展语法让事情变得更简单。

总之,如果你非要用ES3来实现方法,你可以这样做:

// ES3 viersion
Function.prototype.myCall = function(thisArg){
   if(typeof this != 'function'){
      throw new Error('the caller must be a function')
   } 
   if(thisArg === null || thisArg === undefined){
      thisArg = window
   } else {
      thisArg = new Object(thisArg)
   }
   const args = []
   for(var i = 1;i < arguments.length;i ++){
      args.push('arguments[' + i + ']')
   }
   thisArg.fn = this
   const res = eval('thisArg.fn(' + args + ')')
   delete thisArg.fn
   return res
}

上面的版本与您的相似。但是如果允许使用 ES6,你可以像这样更高效地进行:

// ES6 verison
Function.prototype.myCall = function(thisArg,...args){
  if(typeof this != 'function'){
    throw new Error('the caller must be a function')
  }
  if(thisArg === null || thisArg === undefined){
    thisArg = window
  } else {
    thisArg = new Object(thisArg)
  }
  thisArg.fn = this
  const res = thisArg.fn(...args)
  delete thisArg.fn
  return res 
}

然而,值得注意的是这两个版本都不是标准实现。