var functionName = функция () {} по сравнению с функцией functionName () {}

6639
задан Richard Garside 15 April 2019 в 07:45
поделиться

7 ответов

Различие - то, что functionOne выражение function и поэтому только определенный, когда та строка достигнута, тогда как functionTwo объявление функции и определяется, как только его окружающая функция или сценарий выполняются (из-за подъем ).

, Например, выражение function:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

И, объявление функции:

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

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

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

Вышеупомянутое на самом деле определяет functionThree независимо от test значение — если use strict не в действительности, в этом случае это просто повышает ошибку.

4903
ответ дан Sudhanshu Vishnoi 22 November 2019 в 19:37
поделиться

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

Для получения дополнительной информации об анонимных функциях и лямбда-исчислении, Википедия является хорошим началом ( http://en.wikipedia.org/wiki/Anonymous_function ).

24
ответ дан ROMANIA_engineer 22 November 2019 в 19:37
поделиться

Сначала я хочу исправить Greg: function abc(){} ограничен по объему также — имя abc определяется в объеме, где с этим определением встречаются. Пример:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

, Во-вторых, возможно объединить оба стиля:

var xyz = function abc(){};

xyz будет определенным, как обычно, abc не определено во всех браузерах, но Internet  Проводник — не полагайтесь на то, чтобы он был определенным. Но это будет определено в его теле:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

, Если Вы хотите исказить функции на всех браузерах, используйте этот вид объявления:

function abc(){};
var xyz = abc;

В этом случае, и xyz и abc псевдонимы того же объекта:

console.log(xyz === abc); // prints "true"

Один неопровержимый довод для использования объединенного стиля является атрибутом "имени" функциональных объектов ( не поддерживаемый Internet  Проводник ). В основном при определении функции как [1 136]

function abc(){};
console.log(abc.name); // prints "abc"

, ее имя автоматически присвоено. Но когда Вы определяете его как [1 137]

var abc = function(){};
console.log(abc.name); // prints ""

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

Другое серьезное основание использовать объединенный стиль состоит в том, чтобы использовать короткое внутреннее имя, чтобы относиться к себе при обеспечении длинного неконфликтующего имени внешних пользователей:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

В примере выше мы можем сделать то же с внешним именем, но это будет слишком громоздким (и медленнее).

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

В глубине души, JavaScript рассматривает оба оператора по-другому. Это - объявление функции:

function abc(){}

abc здесь определяется везде в текущей области:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

кроме того, это подняло через return оператор:

// We can call it here
abc(); // Works
return;
function abc(){}

Это - выражение function:

var xyz = function(){};

xyz здесь определяется от точки присвоения:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

Объявление функции по сравнению с выражением function является настоящей причиной, почему существует различие, продемонстрированное Greg.

Забавный факт:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

Лично, я предпочитаю объявление "выражения function", потому что этот путь я могу управлять видимостью. Когда я определяю функцию как [1 149]

var abc = function(){};

, я знаю, что определил функцию локально. Когда я определяю функцию как [1 150]

abc = function(){};

, я знаю, что определил ее глобально, если это я не определил abc нигде в цепочке объемов. Этот стиль определения эластичен, даже когда используется в eval(). В то время как определение

function abc(){};

зависит от контекста и может оставить Вас предполагающий, где это на самом деле определяется, особенно в случае [1 129] — ответ: Это зависит от браузера.

1905
ответ дан Merlin 22 November 2019 в 19:37
поделиться

С точки зрения стоимости обслуживания кода, именованные функции более предпочтительны:

  • независимо от места, где они объявлены (но все же ограничены объемом).
  • Более устойчивые к ошибкам, таким как условная инициализация (вы все еще можете переопределить, если хотеть).
  • Код становится более читабельным путем выделения локальных функций отдельно от функциональности охвата. Обычно в области применения функциональность идет первая, а затем объявления локальных функций.
  • В отладчике вы четко увидите имя функции в стеке вызовов вместо «анонимной / оцененной» функции.

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

Исторически анонимные функции появились из неспособности JavaScript в качестве языка для перечисления членов с именами функций:

{
    member:function() { /* How do I make "this.member" a named function? */
    }
}
29
ответ дан 22 November 2019 в 19:37
поделиться

Два фрагмента кода, которые вы разместили там, почти для всех целей будут вести себя одинаково.

Однако разница в поведении заключается в том, что в первом варианте ( var functionOne = function () {} ) эта функция может быть вызвана только после этого места в коде.

Во втором варианте ( function functionTwo () ) функция доступна для кода, который выполняется выше, где функция объявлена.

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

Дополнительная техническая информация

В JavaScript есть три способа определения функций.

  1. Ваш первый фрагмент показывает выражение функции . Это включает использование оператора «функции» для создания функции - результат этого оператора может быть сохранен в любой переменной или свойстве объекта. Таким образом, выражение функции является мощным. Выражение функции часто называют «анонимной функцией», потому что у него не обязательно должно быть имя,
  2. Ваш второй пример - это объявление функции . При этом используется оператор «функция» для создания функции. Функция становится доступной во время синтаксического анализа и может быть вызвана в любом месте этой области. Вы все еще можете сохранить его в переменной или свойстве объекта позже.
  3. Третий способ определения функции - это конструктор «Function ()» , который не показан в вашем исходном сообщении. Не рекомендуется использовать его, так как он работает так же, как eval () , у которого есть свои проблемы.
121
ответ дан 22 November 2019 в 19:37
поделиться

Важная причина состоит в том, чтобы добавить одну и только одну переменную в качестве «корня» вашего пространства имен ...

var MyNamespace = {}
MyNamespace.foo= function() {

}

или

var MyNamespace = {
  foo: function() {
  },
  ...
}

Есть много методов для размещения пространств имен. Это стало более важным с появлением множества доступных модулей JavaScript.

См. Также Как объявить пространство имен в JavaScript?

61
ответ дан 22 November 2019 в 19:37
поделиться

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

Тонкое различие между двумя способами заключается в том, что при запуске процесса Variable Instantiation (до фактического выполнения кода) все идентификаторы, объявленные с помощью var , будут инициализированы с помощью undefined , а те, которые используются в FunctionDeclaration , будут доступны с этого момента, например:

 alert(typeof foo); // 'function', it's already available
 alert(typeof bar); // 'undefined'
 function foo () {}
 var bar = function () {};
 alert(typeof bar); // 'function'

Назначение bar FunctionExpression происходит до тех пор, пока время выполнения.

Глобальное свойство, созданное FunctionDeclaration , может быть перезаписано без каких-либо проблем, как и значение переменной, например:

 function test () {}
 test = null;

Еще одно очевидное различие между вашими двумя примерами заключается в том, что первая функция не имеет name, но у второго оно есть, что может быть действительно полезно при отладке (т. е. проверке стека вызовов).

Что касается вашего первого отредактированного примера ( foo = function () {alert ('hello!');}; ), это незадекларированное задание, я настоятельно рекомендую вам всегда использовать var ключевое слово.

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

Кроме того, необъявленные присвоения вызывают ошибку ReferenceError в ECMAScript 5 в строгом режиме .

Необходимо прочитать:

Примечание : Этот ответ был объединен с другим вопросом , в котором основное сомнение и заблуждение со стороны OP заключалось в том, что идентификаторы объявленный с помощью FunctionDeclaration , не может быть перезаписан, что не так.

139
ответ дан 22 November 2019 в 19:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: