2

I was try to do the native implementation of call method in javascript. Here we need to handle the object which we pass in the call function and additional params. i handle the additional params using eval() method. is there any efficient way to do the native call() function implementation. here is my code

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");
3
  • Why would you want to do this? Commented Apr 29, 2019 at 16:57
  • want to understand how call function is work behind the screen Commented Apr 29, 2019 at 17:04
  • 1
    Well to truly do that you'd have to be looking at the internal implementation, which definitely does not involve eval(). It's almost certainly not JavaScript code. Commented Apr 29, 2019 at 17:07

2 Answers 2

1

Without call.

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

but i see no reason for this

Sign up to request clarification or add additional context in comments.

Comments

0

It seems that your call method implementation is a ES3 version because you create a params list string and use eval to execute the function. But you also have used rest params here which proves that the browser supports ES6. So we can use spread syntax to make things easier.

In a word, if you have to implement the method using ES3, you can do it like this:

// 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
}

The version above is similar to yours. But if ES6 is allowed to use, you can do it more efficiently like this:

// 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 
}

However, what's notable is that both of these 2 versions aren't standard implementations.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.