33

Is it possible to somehow set a name for anonymous functions?

There is no need to add function names to the namespace for anonymous functions but I would like to avoid seeing a large amount of (?) in my javascript debugger so I can keep the call stack trace informative.

Also can I safely pass normal declared functions as arguments instead of anonymous functions or will I walk into some strange errors. It seems to work.

$("object").bind("click", function() { alert("x"); });
$("object").bind("click", function debuggingName() { alert("x"); });

[Edit]

I meant something along the likes of

$("object").bind("click", function() { Function.Name = "debuggingName"; alert("x"); });
asked Oct 4, 2010 at 9:57
6
  • 4
    @Raynos - a named anonymous function is a contradiction in terms!! Commented Oct 4, 2010 at 10:00
  • Are you getting some error when you use your second construct above? Commented Oct 4, 2010 at 10:00
  • I just want to set something within an anonymous function that the debugger can pick up and display as a useful debugging function name. I want to use them exactly as I would use anonymous functions Commented Oct 4, 2010 at 10:27
  • @raynos: have you tried $("object").bind("click", function MY_NOT_SO_ANONYMOUS_FUNCTION_NAME () { alert("x"); }); Commented Oct 4, 2010 at 12:17
  • 1
    @Raynos: Sorry, I must have missed that you already wrote that. It's exactly the same as your second example. Commented Oct 4, 2010 at 13:40

6 Answers 6

23

Your second example is using a named function expression, which works fine in most browsers but has some problems in IE that you should be aware of before using it. I recommend reading kangax's excellent article on this subject.

Ron Burk
6,3211 gold badge23 silver badges20 bronze badges
answered Oct 4, 2010 at 10:18
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you, I was worried that passing a named function expression may cause errors.
Oh that's a lovely article. I didn't notice there was actaully a difference between named function expressions and function declaration.
Although actaully I believe my second example above is a function statement. Unles you count assigning the function declaration to arguments[1] as a named function expression. And I was starting to get a feeling that I understood javascript.
Your second example is definitely a named function expression. It looks identical to a function declaration except for the context: a function declaration isn't valid where an expression is expected (such as when passing a function parameter, as your example does). A function statement is another thing entirely: that's a Mozilla extension to ECMAScript to prevent a function declaration within, say, an if block from being a syntax error. kangax's article covers that too: kangax.github.com/nfe/#function-statements
Oh bah I read the article wrong. Yes its a function expression. Out of curiosity does the phrase "named function expression" apply to such statements as var name = function thing() {} ? Or generally when are function expressions considered "named"
|
7

You could do something like this with arrow functions, it works for me on Node.

const createTask = ([name, type = 'default']) => {
 const fn = () => { ... }
 Object.defineProperty(fn, 'name', {
 value: name,
 configurable: true,
 })
 return fn
}

MDN is somewhat misleading here:

You cannot change the name of a function, this property is read-only...

To change it, you could use Object.defineProperty() though.

This answer provides more details.

answered Jan 15, 2019 at 16:31

Comments

1

With ECMAScript2015 (ES2015, ES6) language specification, it is possible to do without the use of slow and unsafe eval function and without Object.defineProperty method which both corrupts function object and does not work in some crucial aspects anyway.

See, for example, this nameAndSelfBind function that is able to both name anonymous functions and renaming named functions, as well as binding their own bodies to themselves as this and storing references to processed functions to be used in an outer scope (JSFiddle):

(function()
{
 // an optional constant to store references to all named and bound functions:
 const arrayOfFormerlyAnonymousFunctions = [],
 removeEventListenerAfterDelay = 3000; // an auxiliary variable for setTimeout
 // this function both names argument function and makes it self-aware,
 // binding it to itself; useful e.g. for event listeners which then will be able
 // self-remove from within an anonymous functions they use as callbacks:
 function nameAndSelfBind(functionToNameAndSelfBind,
 name = 'namedAndBoundFunction', // optional
 outerScopeReference) // optional
 {
 const functionAsObject = {
 [name]()
 {
 return binder(...arguments);
 }
 },
 namedAndBoundFunction = functionAsObject[name];
 // if no arbitrary-naming functionality is required, then the constants above are
 // not needed, and the following function should be just "var namedAndBoundFunction = ":
 var binder = function() 
 { 
 return functionToNameAndSelfBind.bind(namedAndBoundFunction, ...arguments)();
 }
 // this optional functionality allows to assign the function to a outer scope variable
 // if can not be done otherwise; useful for example for the ability to remove event
 // listeners from the outer scope:
 if (typeof outerScopeReference !== 'undefined')
 {
 if (outerScopeReference instanceof Array)
 {
 outerScopeReference.push(namedAndBoundFunction);
 }
 else
 {
 outerScopeReference = namedAndBoundFunction;
 }
 }
 return namedAndBoundFunction;
 }
 // removeEventListener callback can not remove the listener if the callback is an anonymous
 // function, but thanks to the nameAndSelfBind function it is now possible; this listener
 // removes itself right after the first time being triggered:
 document.addEventListener("visibilitychange", nameAndSelfBind(function(e)
 {
 e.target.removeEventListener('visibilitychange', this, false);
 console.log('\nEvent listener 1 triggered:', e, '\nthis: ', this,
 '\n\nremoveEventListener 1 was called; if "this" value was correct, "'
 + e.type + '"" event will not listened to any more');
 }, undefined, arrayOfFormerlyAnonymousFunctions), false);
 // to prove that deanonymized functions -- even when they have the same 'namedAndBoundFunction'
 // name -- belong to different scopes and hence removing one does not mean removing another,
 // a different event listener is added:
 document.addEventListener("visibilitychange", nameAndSelfBind(function(e)
 {
 console.log('\nEvent listener 2 triggered:', e, '\nthis: ', this);
 }, undefined, arrayOfFormerlyAnonymousFunctions), false);
 // to check that arrayOfFormerlyAnonymousFunctions constant does keep a valid reference to
 // formerly anonymous callback function of one of the event listeners, an attempt to remove
 // it is made:
 setTimeout(function(delay)
 {
 document.removeEventListener('visibilitychange',
 arrayOfFormerlyAnonymousFunctions[arrayOfFormerlyAnonymousFunctions.length - 1],
 false);
 console.log('\nAfter ' + delay + 'ms, an event listener 2 was removed; if reference in '
 + 'arrayOfFormerlyAnonymousFunctions value was correct, the event will not '
 + 'be listened to any more', arrayOfFormerlyAnonymousFunctions);
 }, removeEventListenerAfterDelay, removeEventListenerAfterDelay);
})();
answered Mar 2, 2019 at 16:52

Comments

0

I normally do: $("object").bind("click" , function name() { alert("x"); });

and don't run into any problems.

Doing so is encouraged in some of the major libraries:

https://groups.google.com/forum/m/#!topic/firebug/MgnlqZ1bzX8

http://blog.getfirebug.com/2011/04/28/naming-anonymous-javascript-functions/

answered Nov 12, 2014 at 8:47

Comments

-2

If dynamic function name is the issue. You can try this:

function renameFunction(name, fn) {
 return (new Function("return function (call) { return function " + name +
 " () { return call(this, arguments) }; };")())(Function.apply.bind(fn));
} 
renameFunction('dynamicName',function() { debugger })();

source: Nate Ferrero

Kobe
6,4681 gold badge18 silver badges38 bronze badges
answered Nov 17, 2015 at 13:18

2 Comments

I've just seen a better solution for that at stackoverflow.com/questions/5871040/…
Don't ever do this. It's foolish and verbose.
-3

An anonymous function is a function without a name, it is executed from where it is defined. Alternatively, you can define the debugging function before using it.

function debuggingName() { 
 alert("x"); 
}
$("object").bind("click", debuggingName);
answered Oct 4, 2010 at 10:14

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.