Naming an anonymous function
有可能以某种方式为匿名函数设置名称吗?
没有必要为匿名函数添加函数名称到命名空间,但我想避免在我的javascript调试器中看到大量(?),这样我就可以保持调用堆栈跟踪信息。
我也可以安全地将正常声明的函数作为参数而不是匿名函数传递,或者我会遇到一些奇怪的错误。 它似乎工作。
1 2 3 | $("object").bind("click", function() { alert("x"); }); $("object").bind("click", function debuggingName() { alert("x"); }); |
[编辑]
我的意思是喜欢的东西
1 | $("object").bind("click", function() { Function.Name ="debuggingName"; alert("x"); }); |
你的第二个例子是使用一个命名的函数表达式,它在大多数浏览器中都能正常工作,但在使用它之前你应该注意IE中的一些问题。我建议阅读kangax关于这个主题的优秀文章。
您可以使用箭头功能执行此类操作,它适用于Node。
1 2 3 4 5 6 7 8 9 10 | const createTask = ([name, type = 'default']) => { const fn = () => { ... } Object.defineProperty(fn, 'name', { value: name, configurable: true, }) return fn } |
MDN在这里有点误导:
You cannot change the name of a function, this property is read-only...
To change it, you could use Object.defineProperty() though.
这个答案提供了更多细节。
使用ECMAScript2015(ES2015,ES6)语言规范,可以不使用慢速和不安全的eval函数,也可以不使用Object.defineProperty方法,它既破坏了函数对象,又无论如何都无法在某些关键方面起作用。
例如,请参阅此
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | (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(' Event listener 1 triggered:', e, ' this: ', this, ' removeEventListener 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(' Event listener 2 triggered:', e, ' this: ', 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(' After ' + 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); })(); |
如果动态函数名称是问题。你可以试试这个:
1 2 3 4 5 6 | 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 })(); |
来源:Nate Ferrero
我通常这样做:
$("对象")。绑定("点击"
,function name(){
警报("X");
});
并且不要遇到任何问题。
在一些主要的图书馆鼓励这样做:
https://groups.google.com/forum/m/#!topic/firebug/MgnlqZ1bzX8
http://blog.getfirebug.com/2011/04/28/naming-anonymous-javascript-functions/
匿名函数是没有名称的函数,它从定义的位置执行。或者,您可以在使用之前定义调试功能。
1 2 3 4 5 | function debuggingName() { alert("x"); } $("object").bind("click", debuggingName); |