clentfort
clentfort

Reputation: 2504

Overwrite toString for specific function

Look edits below! I am currently looking for a way to overload the toString method of one specific function that is generated dynamically (returned by function). I know I can overload the toString function of Function.prototype, but this will overload all toString functions of all functions, I want to avoid this.

My example function:

var obj = {
    callme: function() {
        return function() {
            // Dynamically fetch correct string from translations map
            return "call me, maybe"; 
        }
    }
}
// Binding callme to func, allowing easier access
var func = obj.callme.bind(obj); 
console.log(func, func())

So far I have tried to just treat the function like a regular JavaScript object.

func.toString = function() {
    return this();
}

This results in the Function.prototype.toString still being called instead of func.toString.

Trying to access the func.prototype is not possible, the prototype property is undefined since it is a function not an object. Overwriting toString of Function.prototype is not an option, changing func to an object is also not possible since it might brake compatibility with older parts of the code.

Edit: The attempts made above are obviously not working since I am overwriting the toString of the function func and not the toString of the returned function. Now a better question: Is there an elegant way to overwrite the toString of all functions that are returned by func so that they "share" the same toString. (Means I don't have to specify the toString for every returned function.)

Upvotes: 5

Views: 622

Answers (2)

Brandan
Brandan

Reputation: 14983

You can define toString on the returned function in callme by storing it in a variable before returning it:

var obj = {
  callme: function (){
    function toString(){
      return this();
    }

    var f = function (){
      // Dynamically fetch correct string from translations map
      return "call me, maybe"; 
    };

    f.toString = toString;

    return f;
  }
};

var func = obj.callme.bind(obj);
console.log(func);                //=> [Function]
console.log(func());              //=> { [Function] toString: [Function: toString] }
console.log(func().toString());   //=> 'call me, maybe'

Upvotes: 3

ChrisThompson
ChrisThompson

Reputation: 2008

If you need a custom value couldn't you just write a method for that instead of trying to overwrite the toString prototype.

Otherwise if you need to change it for all you can do something like:

String.prototype.toString = function() {return this+"test";}

Upvotes: 0

Related Questions