Объявление функции как var вместо функции

28

Все больше и больше я вижу, что функции объявляются как

var foo = function() {

    // things
};

Вместо того, как я узнал, как

function foo() {

    // things
}

Какая разница? Лучшая производительность? Объем? Должен ли я использовать этот метод?

Стив Роббинс
источник
Стоит отметить, что в JavaScript функции являются гражданами первого класса . Это позволяет вам передавать поведение как объекты. Это очень полезно для обратных вызовов и делегирования, между прочим.
Chris Bye
Область применения . Обтекание имени переменной "вещи" по существу /, мы надеемся, предотвращает конфликты имен "вещей", которые она переносит, включая другие JavaScript (файлы). Еще один способ думать о том, что вы создали пространство имен "foo".
радар Боб

Ответы:

25

var foo = function() {} определяет переменную, которая ссылается на анонимную функцию.

function foo() {}определяет именованную функцию foo.

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

В конце концов, какой из них вы используете, в значительной степени продиктован вашим конкретным вариантом использования (Javascript очень интересен;)). Если вы в конечном итоге используете первый, я настоятельно рекомендую вам назвать функцию:

var foo = function MY_function() {}, Это соглашение об именах помогает вашему стеку вызовов отладчика не быть бесполезным.

Демиан Брехт
источник
1
Есть глупость на функцию () МОЙ ...
Эрик Реппен
1
@ Демьян Брехт, а как насчет подхода var foo = function foo () {...}?
Шабун
@shabunc: А как насчет этого? Это указано в последнем абзаце моего ответа.
Демиан Брехт
@Demian Brecht, нет, на самом деле в последнем абзаце вызывается переменная и вызывается fooфункцияMY_function
shabunc
@shabunc: имя не имеет значения. Важным является значение в стеке вызовов. Например, [NAMESPACE] _ [fn name] - это соглашение, используемое Mozilla. Само название не имеет значения, если ваше соглашение согласовано на протяжении всего проекта.
Демиан Брехт
13

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

//someFunction(); //wouldn't work when uncommented
var someFunction = function(){ alert('yay'); };

В этом случае выражение func является анонимным, но присваивается переменной var для справки. Это отличается от помеченного оператора функции следующими способами:

  • он не может быть поднят (вызван до того, как определен)
  • new someFunction().constructor.name === 'someFunction';//false экземпляры не получают имя переменной для constructor.name, потому что ссылка на функцию назначена переменной, но переменная, а не функция, привязана к имени переменной

В помеченном операторе функции:

//someFunction(); //works when uncommented
function someFunction(){ alert('yay'); }
  • грузоподъемные работы
  • new someFunction().constructor.name === 'someFunction'; //true имя напрямую связано с функцией.

Вообще говоря, на самом деле нет особой причины делать выражение для var, если только вы не хотите, чтобы вызовы не выполнялись, если что-то перемещается или вы определяете / назначаете метод в одной строке. Я на самом деле считаю подъем полезным для организации объектов с внутренними определениями функций и методов в нижней части, чтобы я мог перейти к реальному поведению объекта и выполнить однострочные публичные определения методов (просто назначив функции this.с одинаковыми именами) все в одном место для удобства пользования. Вы должны всегда пытаться использовать помеченные операторы для конструкторов, IMO, чтобы вы могли определить «тип» объекта через его конструктор.

Эрик Реппен
источник
8

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

Например:

SomeThing('abc', function(a,b) {return a*b;});

против ...

function tmp(a,b) { 
    return a*b;
}

SomeThing('abc', tmp);

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

Посмотрите на /programming/111102/how-do-javascript-closures-work

gahooa
источник
4

Основное практическое отличие - подъем. Например:

foo(); // alerts 'hello'
function foo() {alert('hello');}

против

foo(); // throws an error since foo is undefined
var foo = function() {alert('hello');}

Кроме того, это неопределенное поведение

function foo(){
  if (true) {
    function bar(){}
  }
  bar();
}

пока это нормально.

function foo(){
  if (true) {
    var bar = function(){}
  }
  bar();
}
Остин
источник
7
Нет ничего плохого в определении функции внутри функции в JS. Не так много мест, где вы не можете определить функцию в JS.
Эрик Реппен
2
@ErikReppen Вы определенно не можете использовать объявления функций внутри нефункциональных блоков (например, в операторе if). Я не могу найти, где я читаю, они не могут быть использованы в другой функции.
Остин
@Austin Нет ничего плохого и в определении функции внутри ifоператора!
Тим
@Austin: Возможно, вы читали это в w3schools? ;)
Демиан Брехт
2
@ErikReppen Функциональные выражения можно использовать где угодно. Объявления функций не могут быть. См. Stackoverflow.com/questions/10069204/…
Остин