简体   繁体   中英

Javascript rename function (not variable name)

I am trying to change the name of the function that is given by .toString() , or create a new function with a new name but the same body.

function func() {}
func.toString() // returns 'function func() {}'
changename(func, "newname") // this is the functionality that I am trying to achieve
func.toString() // should now return 'function newname() {}'

I have tried using Object.defineProperty() which sucessfully updates the value returned by func.name but not func.toString() .

Object.defineProperty(func, "name", {
  value: "newname",
  writable: true,
});
func.name // returns 'newname'
func.toString() // still returns 'function func() {}'

Edit: Reason for wanting to do this I need take take an arbitrary function with an unknown name and write it to a file with a known name, for example (using nodejs):

const fs = require("fs");
changename(func, "newname");
fs.writeFileSync("tmp.js", func.toString());

tmp.js then contains:

function newname() {}

If all you need to do is write the code of the function to a file, just regex replace the name with whatever you want:

let func = // whatever;

let funcCode = func.toString();
funcCode = funcCode.replace(/^function [^(]*(.*)$/, "function newName$1");

Now funcCode has the text you can dump out to a file.

Changing the reported "name" property of an actual function object is another story entirely, and is either impossible or impractical at best. If you're just working with the text of the function, it's easy.

If you are okay with extending toString function, this should work:

function func() {}
func.toString() // returns 'function func() {}'
changeName=function(funcToExtend, name){
    funcToExtend.toString = () => name;
}
changeName(func,"new name");
func.toString(); // new name 

One way to do this is to change how the toString function works. I don't think this is a good solution but I came up with this:

function test(){
    console.log('hello');
}
test.newName = 'helloFunc';
test.toString = function(){
    var str = Function.prototype.toString.call(this);
    return 'function ' + this.newName + str.substring(str.indexOf('('), str.length);

}

console.log(test.toString());

I believe that a much nicer solution could implement the Function constructor. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

If you want just a new String with the new name, you can do this way:

 function func() {} console.log(func.toString()) Object.prototype.changeName = function (newName) { return "function " + newName + "(){}"; } let newNameFunction = func.changeName("newName") console.log(newNameFunction);

But this way, you don't have the body of the function.

Edit:

You may just want to use instances of the functions. This may help to create required instances with the same function and different outputs.

// Sample data to use for different outputs
        var objRequiredFunctionReferences = [
            {
                name: "name_1",
                var_val: "variable value 1"
            },

            {
                name: "name_2",
                var_val: "variable value 2"
            },
        ];

        // Container of required functions which can be refferenced
        var objFunctions = {};

        // Main function to run
        function do_something(objRequired) {
            this.some_name = objRequired.name;
            this.some_variable = objRequired.var_val;
            this.toString = function (){
                return "Running " + this.some_name + ", with variable value " + this.some_variable;
            };
        }

        // Initialise different instances
        for (var i = 0; i < objRequiredFunctionReferences.length; i++){
            var newFunc = new do_something(objRequiredFunctionReferences[i]);
            objFunctions[objRequiredFunctionReferences[i].name] = newFunc;
        }

        // Run functions
        for(var j = 0; j < objFunctions.length; j++){
            objFunctions[i].toString();
        }

        /// objFunctions.name_1.toString();
        /// "Running name_1, with variable value variable value 1"
        /// objFunctions.name_2.toString();
        /// "Running name_2, with variable value variable value 2"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM