Creating a function with a custom name is not something you can do easily out of the box in ECMAScript. Thankfully, ECMAScript comes with a custom function constructor.
First, the basic code, which will give most of you want you want:
The above will create an anonymous function, which when called creates the named function (using the name variable). This functionality is a good substitute for when you can’t use eval()
but you need a function with a custom name. Eval is generally useless in ES5 strict mode for a number of good reasons, so its best avoided.
However, an issue with the code above is that we had to write the main code into a string. This sucks because it makes it difficult to debug (i.e., we can’t easily set break points), so we want to avoid that as much as possible. The solution is to make the main function external, pass it as an argument to the Function constructor to call it.
Another advantage here is that we can set private variables inside our custom function, which can then be mixed with public arguments. Check this out!:
You can basically the start doing cool things from there, like:
The above is mega useful for dynamically implementing custom DOM-like interfaces… like shims. Enjoy! 🙂
Actually this is as bad as eval. The code inside the string is not compiled, because javascript engine have no way to know how will the function look like, so every time you call it it will be parsed again, and again, and again. It hits the performance really bad.
I agree. It’s certainly not ideal – but it’s a pretty special case. The use case is that it’s ever called once.
I know this is over a year old, but I came across it while looking for a good way to fix a problem we’re having.
Theoretically you could put the return into a cache and any time after the first you’d call the cache instead. So you’d take a minor hit on the first instantiation but then never again.
Hello! I’ve been working on a projet to simulate the behavior of classes in Java.
https://github.com/reduardo7/sjsClass/
I hope someone else will help this!
Cheers!
Hi,
I found your page while I was looking for help with my requirement.
In my case, I want to return a value from the dynamic function
Pasted the code below, the custom function is getting executed but am getting ‘undefined’ for ‘returned’. Would you be able to help with this?
Thanks
var customFunction = function (name, data) {
return ‘something’;
};
var returned = null;
returned = func(e, results[e]);
console.log(returned);
if(returned){
group._currentData= returned;
}
I don’t well see the usefullness of adding a name to the function object created with the constructor…
code:
var d = document.body.appendChild(document.createElement(“div”));
d.style.border = “solid 1px red”;
var print = (function() {
var a = 0;
var p = function(txt) {
var el = d.appendChild(document.createElement(“div”))
el.innerHTML = String(a) + “: ” + txt;
a++;
}
return (p)
})();
var name = “foo”;
var customAction = function(x, y) {
print(“x+y=” + (x + y));
};
//implement it
var func = new Function(“action”, “return function ” + name + “(x,y){ print(action.toString());action(x,y) };”)(customAction);
//test it
func(1, 2);
print(func.toString());
customAction = {};
func(1, 2);
print(func.toString());
print(customAction);
// is name useful ??
var f1 = function fun1(x, y) {
return (x + y)
};
print(f1(1, 2));
try {
print(fun1(1, 2))
} catch (er) {
print(er.message)
};
print(f1.name);
oputput:
0: function (x, y) { print(“x+y=” + (x + y)); }
1: x+y=3
2: function foo(x,y){ print(action.toString());action(x,y) }
3: function (x, y) { print(“x+y=” + (x + y)); }
4: x+y=3
5: function foo(x,y){ print(action.toString());action(x,y) }
6: [object Object]
7: 3
8: fun1 is not defined
9: fun1
i found this on (http://http://helephant.com/2008/08/23/javascript-anonymous-functions/) but i appreciate other arguments for my learning of javascript :
The function’s name can be used to call the function from inside the function itself. That can be useful for recursive functions.
var thingsToDoToday = function flyToTheMoon() {
if(!onTheMoon)
flyToTheMoon();
else
alert(“One small step for a man..”);
}
thingsToDoToday();
It can also useful for debugging because you can see the function’s name in a call stack. Anonymous functions generally all look the same in the call stack. If you have a nasty debugging situation, sometimes giving names to the functions you are interested in can make things clearer.