代码之家  ›  专栏  ›  技术社区  ›  Raynos

命名匿名函数

  •  20
  • Raynos  · 技术社区  · 14 年前

    是否可以为匿名函数设置名称?

    不需要为匿名函数向命名空间添加函数名,但我希望避免看到大量(?)在我的javascript调试器中,这样我就可以保持调用堆栈跟踪的信息性。

    另外,我可以安全地将正常声明的函数作为参数而不是匿名函数传递,或者我会遇到一些奇怪的错误。它似乎起作用了。

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

    [编辑]

    我的意思是

    $("object").bind("click", function() { Function.Name = "debuggingName"; alert("x"); });
    
    6 回复  |  直到 6 年前
        1
  •  17
  •   Tim Down    14 年前

    第二个示例是使用 命名函数表达式 它在大多数浏览器中都可以正常工作,但在IE中有一些问题,在使用之前应该注意到。我推荐阅读 kangax's excellent article on this subject .

        2
  •  1
  •   Jack Steam Him Ho    6 年前

    您可以对arrow函数执行类似的操作,它在node上为我工作。

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

    MDN is somewhat misleading here:

    不能更改函数名,此属性是只读的…

    要改变它, 你可以使用 对象.定义属性() 虽然 .

    This answer provides more details.

        3
  •  0
  •   Andrew Luhring    10 年前

    我通常这样做: $(“对象”).bind(“单击” ,函数名()。{ 警报(“X”); (});

    不要碰到任何问题。

    一些主要图书馆鼓励这样做:

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

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

        4
  •  0
  •   Community CDub    8 年前

    如果 动态 函数名是问题所在。您可以尝试以下操作:

    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 at How to dynamically set a function/object name in Javascript as it is displayed in Chrome

        5
  •  0
  •   DDRRSS    6 年前

    有了ECMAScript2015(ES2015,ES6)语言规范,就可以不使用慢速和不安全的语言。 eval 功能和无功能 Object.defineProperty 这种方法既破坏了函数对象,又不适用于某些关键方面。

    例如,请参见 nameAndSelfBind 能够同时命名匿名函数和重命名命名函数的函数,以及将其自身的实体绑定为 以及存储对要在外部作用域中使用的已处理函数的引用( 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);
    })();
    
        6
  •  -3
  •   Q_Mlilo    14 年前

    匿名函数是一个没有名称的函数,它是从定义它的地方执行的。或者,您可以在使用调试函数之前定义它。

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