Наименование анонимной функции - PullRequest
20 голосов
/ 04 октября 2010

Можно ли как-то установить имя для анонимных функций?

Нет необходимости добавлять имена функций в пространство имен для анонимных функций, но я бы не хотел видеть большое количество (?) В моем отладчике javascript, чтобы я мог сохранять информативность трассировки стека вызовов.

Также могу ли я безопасно передавать обычные объявленные функции в качестве аргументов вместо анонимных функций, или я буду сталкиваться с некоторыми странными ошибками. Вроде работает.

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

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

[Изменить]

Я имел в виду что-то вроде

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

Ответы [ 6 ]

19 голосов
/ 04 октября 2010

Ваш второй пример использует именованное выражение функции , которое прекрасно работает в большинстве браузеров, но имеет некоторые проблемы в IE, о которых вам следует знать перед его использованием. Я рекомендую прочитать отличную статью kangax на эту тему .

1 голос
/ 15 января 2019

Вы можете сделать что-то подобное с функциями стрелок, у меня это работает на Node.

const createTask = ([name, type = 'default']) => {
  const fn = () => { ... }

  Object.defineProperty(fn, 'name', {
    value: name,
    configurable: true,
  })

  return fn
}

MDN здесь несколько вводит в заблуждение:

Вы не можете изменить имя функции, это свойство доступно только для чтения ...

Чтобы изменить его, вы можете использовать Object.defineProperty () хотя .

Этот ответ содержит более подробную информацию.

0 голосов
/ 02 марта 2019

С помощью спецификации языка ECMAScript2015 (ES2015, ES6) можно обойтись без использования медленной и небезопасной eval функции и без Object.defineProperty метод, который портит функциональный объект и в любом случае не работает в некоторых важных аспектах.

См., Например, эту nameAndSelfBind функцию, которая может как именовать анонимные функции, так и переименовывать именованные функции, а также привязывать их собственные тела к себе как this и хранить ссылки на обработанные функции для использоваться во внешней области ( 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);
})();
0 голосов
/ 17 ноября 2015

Если динамическое имя функции является проблемой.Вы можете попробовать это:

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 })();

источник: Нейт Ферреро на Как динамически установить имя функции / объекта в Javascript, как оно отображается в Chrome

0 голосов
/ 12 ноября 2014

Я обычно делаю: $ ( "Объект"). Bind ( "щелчок" , имя функции () { предупреждение ( "х"); });

и не сталкивайтесь с какими-либо проблемами.

В некоторых основных библиотеках рекомендуется делать это:

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

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

0 голосов
/ 04 октября 2010

Анонимная функция - это функция без имени, она выполняется там, где она определена.Кроме того, вы можете определить функцию отладки перед ее использованием.

function debuggingName() { 
    alert("x"); 
}

$("object").bind("click", debuggingName);
...