У нас есть два разных способа сделать выражение функции в JavaScript:

Выражение именованной функции (NFE) :

var boo = function boo () {
  alert(1);
};

выражение анонимной функции :

var boo = function () {
  alert(1);
};

И оба они могут быть вызваны с помощью boo();. Я действительно не понимаю, почему / когда я должен использовать анонимные функции и когда я должен использовать выражения именованных функций. Какая разница между ними?

В случае выражения анонимной функции, функция является анонимной — буквально, она не имеет имени. Переменная, которой вы ее назначаете, имеет имя, а функция — нет. (Обновление: это было верно в ES5. Начиная с ES2015 [aka ES6], часто функция, созданная с помощью анонимного выражения, получает истинное имя [но не автоматический идентификатор], читайте дальше …)

Имена полезны. Имена можно увидеть в следах стеков, стеках вызовов, списках точек останова и т. Д. Имена — это хорошая вещь ™.

(Раньше вам приходилось остерегаться выражений именованных функций в более старых версиях IE [IE8 и ниже], потому что они по ошибке создали два совершенно отдельных функциональных объекта в два совершенно разных времени [подробнее в статье моего блога Double take ]. Если вам нужна поддержка IE8 [!!], лучше придерживаться анонимных выражений функций или объявлений функций объявления , но избегать выражений именованных функций.)

Один ключевой момент в Выражение именованной функции заключается в том, что он создает внутриобъектный идентификатор с этим именем для функции в теле функции:

var x = function example() {
    console.log(typeof example); // "function"
};
x();
console.log(typeof example);     // "undefined"

boolean для контроля, разрешены ли функции жирной стрелки ES6 регулярными выражениями. boo. Однако даже с семантикой ES2015 автоматический идентификатор не создается:

var obj = {
    x: function() {
       console.log(typeof x);   // "undefined"
       console.log(obj.x.name); // "x"
    },
    y: function y() {
       console.log(typeof y);   // "function"
       console.log(obj.y.name); // "y"
    }
};
obj.x();
obj.y();

Назначение имени функции выполняется с помощью абстрактной операции SetFunctionName , используемой в различных операциях в спецификации.

Сокращенная версия — это в основном всякий раз, когда выражение анонимной функции появляется справа от чего-то вроде присваивания или инициализации, например:

var boo = function() { /*...*/ };

(или это могут быть методы let или const, а не var С чем вы столкнулись это использование для Scope, как это делается

var obj = {
    boo: function() { /*...*/ }
};

или

doSomething({
    boo: function() { /*...*/ }
});

(последние два на самом деле одно и то же) { *}, результирующая функция будет иметь имя ( Существует важное и преднамеренное исключение: присвоение свойству существующему объекту: boo Что-то простое, как приведенный ниже код, может помочь вам, если вы хотите проверить

Это произошло из-за проблем утечки информации, возникающих при прохождении новой функции. процесс добавления ; подробностей в моем ответе на другой вопрос

obj.boo = function() { /*...*/ }; // <== Does not get a name

Именование функций полезно, если они должны ссылаться на себя (например, для рекурсивных вызовов). Действительно, если вы передаете выражение литеральной функции в качестве аргумента непосредственно в другую функцию, это выражение функции говорится, что Глядя на вывод

не может напрямую ссылаться на себя в строгом режиме ES5, если оно не названо. Например, рассмотрим этот код:

были анонимными ;, нам нужно вместо этого присвоить его переменной до вызова

setTimeout(function sayMoo() {
    alert('MOO');
    setTimeout(sayMoo, 1000);
}, 1000);

. H Вот упрощенное конечное решение: setTimeout. Выражение функции, немного короче и аккуратнее.setTimeout вызов. Таким образом, с выражением именованной функции, немного короче и аккуратнее.

Исторически было возможно написать подобный код даже с использованием выражения анонимной функции, поскольку использование arguments.callee

setTimeout(function () {
    alert('MOO');
    setTimeout(arguments.callee, 1000);
}, 1000);

Я нашел два способа определения уровня масштабирования. Один из способов обнаружения изменений уровня масштабирования основан на том факте, что процентные значения не увеличиваются. Процентное значение относится к ширине области просмотра и, следовательно, не зависит от масштаба страницы. Если вы вставите два элемента, один с позицией в процентах, а другой с одинаковой позицией в пикселях, они разойдутся при увеличении страницы. Найдите соотношение между позициями обоих элементов, и вы получите уровень масштабирования. Смотрите тестовый пример. Например, arguments.callee устарело и полностью запрещено в строгом режиме ES5. Следовательно, MDN рекомендует:

Избегайте использования arguments.callee(), либо присваивая выражениям функции имя , либо используйте объявление функции, где функция должна вызывать себя.

(выделение мое)

Если функция указана как выражение функции, ей может быть присвоено имя.

Он будет доступен только внутри функции (кроме IE8-).

var f = function sayHi(name) {
  alert( sayHi ); // Inside the function you can see the function code
};

alert( sayHi ); // (Error: undefined variable 'sayHi')

Это имя предназначено для надежного рекурсивного вызова функции, даже если оно записано в другую переменную.

Кроме того, имя NFE (выражение именованной функции) МОЖЕТ быть перезаписано с помощью Object.defineProperty(...) Большинство решений, размещенных здесь, требуют jQuery. Если вы ищете независимое от фреймворка решение, попробуйте Grid:

var test = function sayHi(name) {
  Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
  alert( test.name ); // foo
};

test();

Примечание: это невозможно сделать с помощью объявления функций. Это «специальное» имя внутренней функции указывается только в синтаксисе выражения функции.

Лучше использовать выражения именованных функций, когда вы хотите иметь возможность ссылаться на рассматриваемую функцию без необходимость полагаться на устаревшие функции, такие как arguments.callee Глядя на вывод

http://www.easy-coding.de/wiki/html-ajax-und-co/ onload-event-cross-browser-kompatibler-domcontentloaded.html всегда используйте именованные выражения функций , поэтому:

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

  2. Анонимные функции не помогают при отладке, так как вы не видите название функции, которая вызывает проблемы.

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

var foo = function bar() {
    //some code...
};

foo();
bar(); // Error!

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