Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.)

like image 991
clentfort Avatar asked Oct 22 '22 04:10

clentfort


1 Answers

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'
like image 184
Brandan Avatar answered Nov 03 '22 01:11

Brandan