Var functionName = function() {} vs function functionName() {}

Недавно я начал поддерживать чужой код JavaScript. Я исправляю ошибки, добавляю функции, а также пытаюсь привести в порядок код и сделать его более согласованным.

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

Два способа:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

Каковы причины использования этих двух разных методов и каковы плюсы и минусы каждого? Есть ли что-нибудь, что можно сделать одним методом, но нельзя сделать другим?

Ответ 1

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

Например, выражение функции:

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

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

Ответ 2

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

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

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

var xyz = function abc(){};

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

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"

Одной из убедительных причин использования комбинированного стиля является атрибут "name" для объектов функций (не поддерживается Internet Explorer). В основном, когда вы определяете функцию типа

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

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

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

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

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

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

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

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

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

var abc = function(){};

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

abc = function(){};

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

function abc(){};

зависит от контекста и может оставить вас гадать, где он определен, особенно в случае eval() — Ответ: Это зависит от браузера.

Ответ 3

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

Термины:

Быстрый список:

  • Объявление функции

  • "Анонимная" function Expression (которая, несмотря на термин, иногда создает функции с именами)

  • Именованная function Expression

  • Инициализатор функции доступа (ES5+)

  • Выражение функции стрелки (ES2015+) (которое, как и выражения анонимной функции, не содержит явного имени и может создавать функции с именами)

  • Объявление метода в инициализаторе объекта (ES2015+)

  • Объявления конструктора и метода в class (ES2015+)

Объявление функции

Первая форма - это объявление функции, которое выглядит так:

function x() {
    console.log('x');
}

Объявление функции - это объявление; это не утверждение или выражение. Таким образом, вы не следуете за ним с ; (хотя это безвредно).

Объявление функции обрабатывается, когда выполнение входит в контекст, в котором оно появляется, перед выполнением любого пошагового кода. Создаваемой ей функции присваивается собственное имя (x в приведенном выше примере), и это имя помещается в область, в которой появляется объявление.

Поскольку он обрабатывается перед любым пошаговым кодом в том же контексте, вы можете сделать что-то вроде этого:

x(); // Works even though it above the declaration
function x() {
    console.log('x');
}

До ES2015 спецификация не охватывала то, что должен делать движок JavaScript, если вы поместили объявление функции внутри структуры управления, например, try, if, switch, while и т.д., Например:

if (someCondition) {
    function foo() {    // <===== HERE THERE
    }                   // <===== BE DRAGONS
}

И поскольку они обрабатываются до запуска пошагового кода, сложно знать, что делать, когда они находятся в структуре управления.

Хотя это не было указано до ES2015, это было допустимое расширение для поддержки объявлений функций в блоках. К сожалению (и неизбежно), разные двигатели делали разные вещи.

Начиная с ES2015, в спецификации сказано, что делать. Фактически, это дает три отдельных действия:

  1. Если в свободном режиме нет в веб-браузере, движок JavaScript должен делать одно
  2. Если в свободном режиме в веб-браузере, движок JavaScript должен делать что-то еще
  3. Если в строгом режиме (браузер или нет), движок JavaScript должен делать еще одну вещь

Правила для свободных режимов хитры, но в строгом режиме объявления функций в блоках просты: они локальны для блока (они имеют область видимости блока, которая также является новой в ES2015), и они поднимаются наверх блока. Так:

"use strict";
if (someCondition) {
    foo();               // Works just fine
    function foo() {
    }
}
console.log(typeof foo); // "undefined" ('foo' is not in scope here
                         // because it not in the same block)

Выражение "анонимная" function

Вторая распространенная форма называется выражением анонимной функции:

var y = function () {
    console.log('y');
};

Как и все выражения, он вычисляется по достижении пошагового выполнения кода.

В ES5 создаваемая функция не имеет имени (она анонимна). В ES2015, функции по возможности присваивается имя, выводя его из контекста. В приведенном выше примере имя будет y. Нечто подобное происходит, когда функция является значением инициализатора свойства. (Для получения подробной информации о том, когда это происходит, и о правилах, найдите SetFunctionName в спецификации - он появляется повсюду.)

Именованная function Expression

Третья форма - это выражение с именованной функцией ("NFE"):

var z = function w() {
    console.log('zw')
};

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

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

Обратите внимание, что NFE часто являются источником ошибок для реализаций JavaScript. Например, IE8 и более ранние версии обрабатывают NFE совершенно неправильно, создавая две разные функции в два разных момента времени. Ранние версии Safari также имели проблемы. Хорошей новостью является то, что в текущих версиях браузеров (IE9 и выше, текущий Safari) таких проблем больше нет. (Но, к сожалению, на момент написания статьи IE8 все еще широко используется, и поэтому использование NFE с кодом для Интернета в целом все еще проблематично.)

Инициализатор функции доступа (ES5+)

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

var obj = {
    value: 0,
    get f() {
        return this.value;
    },
    set f(v) {
        this.value = v;
    }
};
console.log(obj.f);         // 0
console.log(typeof obj.f);  // "number"

Обратите внимание, что когда я использовал функцию, я не использовал () ! Это потому, что это функция доступа для свойства. Мы получаем и устанавливаем свойство обычным способом, но за кулисами вызывается функция.

Вы также можете создавать функции доступа с помощью Object.defineProperty, Object.defineProperties и менее известного второго аргумента Object.create.

Выражение функции стрелки (ES2015+)

ES2015 приносит нам функцию стрелки. Вот один пример:

var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6

Видите, что n => n * 2 что скрывается в вызове map()? Это функция.

Несколько вещей о функциях стрелок:

  1. Они не имеют свой собственный this. Вместо этого они закрывают this контекст, в котором они определены. (Они также близко над arguments и, где это уместно, super.) Это означает, что this в них так же, как this, где они созданы, и не может быть изменен.

  2. Как вы заметили выше, вы не используете function ключевого слова; вместо этого вы используете =>.

Пример n => n * 2 приведенный выше, является одной из их форм. Если у вас есть несколько аргументов для передачи функции, вы используете parens:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(Помните, что Array#map передает запись в качестве первого аргумента, а индекс - в качестве второго.)

В обоих случаях тело функции является просто выражением; возвращаемое значение функции будет автоматически результатом этого выражения (вы не используете явный return).

Если вы делаете больше, чем просто одно выражение, используйте {} и явный return (если вам нужно вернуть значение), как обычно:

var a = [
  {first: "Joe", last: "Bloggs"},
  {first: "Albert", last: "Bloggs"},
  {first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
  var rv = a.last.localeCompare(b.last);
  if (rv === 0) {
    rv = a.first.localeCompare(b.first);
  }
  return rv;
});
console.log(JSON.stringify(a));

Версия без {... } называется функцией стрелки с телом выражения или кратким телом. (Также: Краткая функция стрелки.) Функция с {... } определяющим тело, является функцией стрелки с телом функции. (Также: функция многословной стрелки.)

Объявление метода в инициализаторе объекта (ES2015+)

ES2015 допускает более короткую форму объявления свойства, которое ссылается на функцию, называемую определением метода; это выглядит так:

var o = {
    foo() {
    }
};

почти эквивалент в ES5 и более ранних версиях:

var o = {
    foo: function foo() {
    }
};

Разница (кроме многословия) в том, что метод может использовать super, а функция - нет. Так, например, если бы у вас был объект, который определил (скажем) valueOf с использованием синтаксиса метода, он мог бы использовать super.valueOf() чтобы получить значение Object.prototype.valueOf которое должно быть возвращено (прежде чем предположительно делать что-то еще с ним), тогда как Версия ES5 должна была бы вместо Object.prototype.valueOf.call(this) сделать Object.prototype.valueOf.call(this).

Это также означает, что метод имеет ссылку на объект, для которого он был определен, поэтому, если этот объект является временным (например, вы передаете его в Object.assign как один из исходных объектов), синтаксис метода может означать, что объект сохраняется в памяти, когда в противном случае он мог бы быть собран сборщиком мусора (если механизм JavaScript не обнаруживает эту ситуацию и не обрабатывает ее, если ни один из методов не использует super).

Объявления конструктора и метода в class (ES2015+)

ES2015 предоставляет нам синтаксис class, включая объявленные конструкторы и методы:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

Выше приведены два объявления функций: одно для конструктора, который получает имя Person, и getFullName для getFullName, которое является функцией, назначенной для Person.prototype.

Ответ 4

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

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

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

Назначение bar FunctionExpression выполняется до выполнения.

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

 function test () {}
 test = null;

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

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

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

Кроме того, необъявленные задания бросают ReferenceError на ECMAScript 5 в Strict Mode.

A должен читать:

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

Ответ 5

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

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

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

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

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

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

  • В вашем первом фрагменте показано выражение функции. Это связано с использованием оператора "function" для создания функции - результат этого оператора может быть сохранен в любой переменной или объекте. Выражение функции является таким мощным. Выражение функции часто называют "анонимной функцией", поскольку оно не должно иметь имени,
  • Второй пример - объявление функции . Для создания функции используется оператор "function". Функция предоставляется во время разбора и может быть вызвана в любом месте этой области. Вы можете сохранить его позже в переменной или объекте.
  • Третий способ определения функции - конструктор "Function()" , который не показан в исходном сообщении. Не рекомендуется использовать это, поскольку он работает так же, как eval(), у которого есть свои проблемы.

Ответ 6

Лучшее объяснение Greg answer

functionTwo();
function functionTwo() {
}

Почему нет ошибок? Нам всегда учили, что выражения выполняются сверху донизу (??)

Потому что:

Объявления функций и объявления переменных всегда перемещаются (hoisted) невидимо в верхнюю часть своей области с помощью интерпретатора JavaScript. Функциональные параметры и языковые имена, очевидно, уже есть. ben cherry

Это означает, что такой код:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

Обратите внимание, что часть присваивания деклараций не была поднята. Только имя поднято.

Но в случае с объявлениями функций также будет поднято тело всей функции:

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------

Ответ 7

Другие комментаторы уже рассмотрели семантическую разницу двух вышеперечисленных вариантов. Я хотел бы отметить стилистическую разницу: только вариация "назначение" может установить свойство другого объекта.

Я часто создаю модули JavaScript с таким шаблоном:

(function(){
    var exports = {};

    function privateUtil() {
            ...
    }

    exports.publicUtil = function() {
            ...
    };

    return exports;
})();

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

(Обратите внимание также, что назначение должно содержать точку с запятой после инструкции, в то время как объявление запрещает ее.)

Ответ 8

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

С

if (condition){
    function myfunction(){
        // Some code
    }
}

это определение myfunction переопределит любое предыдущее определение, так как оно будет выполнено во время синтаксического анализа.

В то время как

if (condition){
    var myfunction = function (){
        // Some code
    }
}

выполняет правильную работу определения myfunction только тогда, когда выполняется condition.

Ответ 9

Важной причиной является добавление одной и только одной переменной в качестве "корня" вашего пространства имен...

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

}

или

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

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

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

Ответ 10

Hoisting - это действие интерпретаторов JavaScript для перемещения всех объявлений переменных и функций в начало текущей объем.

Однако поднимаются только фактические декларации. оставляя задания там, где они есть.

  • переменная/функция, объявленная внутри страницы, глобально доступна для доступа в любой точке этой страницы.
  • переменные/функции, объявленные внутри функции, имеют локальную область. означает, что они доступны/доступны внутри тела функции (scope), они недоступны вне тела функции.

Variable

Javascript называется свободно типизированным языком. Это означает, что переменные Javascript могут содержать значение любого Data-Type. Javascript автоматически позаботится об изменении типа переменной на основе значения/литерала, предоставленного во время выполнения.

global_Page = 10;                                               var global_Page;      « undefined
    « Integer literal, Number Type.   -------------------       global_Page = 10;     « Number         
global_Page = 'Yash';                 |   Interpreted   |       global_Page = 'Yash'; « String
    « String literal, String Type.    «       AS        «       global_Page = true;   « Boolean 
var global_Page = true;               |                 |       global_Page = function (){          « function
    « Boolean Type                    -------------------                 var local_functionblock;  « undefined
global_Page = function (){                                                local_functionblock = 777;« Number
    var local_functionblock = 777;                              };  
    // Assigning function as a data.
};  

Функция

function Identifier_opt ( FormalParameterList_opt ) { 
      FunctionBody | sequence of statements

      « return;  Default undefined
      « return 'some data';
}
  • функции, объявленные внутри страницы, поднимаются на верх страницы, имеющей глобальный доступ.
  • функции, объявленные внутри функционального блока, поднимаются до вершины блока.
  • Возвращаемое значение по умолчанию функции: undefined ', Variable значение по умолчанию объявления также 'undefined'

    Scope with respect to function-block global. 
    Scope with respect to page undefined | not available.
    

Объявление функции

function globalAccess() {                                  function globalAccess() {      
}                                  -------------------     }
globalAccess();                    |                 |     function globalAccess() { « Re-Defined / overridden.
localAccess();                     «   Hoisted  As   «         function localAccess() {
function globalAccess() {          |                 |         }
     localAccess();                -------------------         localAccess(); « function accessed with in globalAccess() only.
     function localAccess() {                              }
     }                                                     globalAccess();
}                                                          localAccess(); « ReferenceError as the function is not defined

Выражение функции

        10;                 « literal
       (10);                « Expression                (10).toString() -> '10'
var a;                      
    a = 10;                 « Expression var              a.toString()  -> '10'
(function invoke() {        « Expression Function
 console.log('Self Invoking');                      (function () {
});                                                               }) () -> 'Self Invoking'

var f; 
    f = function (){        « Expression var Function
    console.log('var Function');                                   f ()  -> 'var Function'
    };

Функция, назначенная переменной Пример:

(function selfExecuting(){
    console.log('IIFE - Immediately-Invoked Function Expression');
}());

var anonymous = function (){
    console.log('anonymous function Expression');
};

var namedExpression = function for_InternalUSE(fact){
    if(fact === 1){
        return 1;
    }

    var localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    //return; //undefined.
    return fact * for_InternalUSE( fact - 1);   
};

namedExpression();
globalExpression();

javascript интерпретируется как

var anonymous;
var namedExpression;
var globalExpression;

anonymous = function (){
    console.log('anonymous function Expression');
};

namedExpression = function for_InternalUSE(fact){
    var localExpression;

    if(fact === 1){
        return 1;
    }
    localExpression = function(){
        console.log('Local to the parent Function Scope');
    };
    globalExpression = function(){ 
        console.log('creates a new global variable, then assigned this function.');
    };

    return fact * for_InternalUSE( fact - 1);    // DEFAULT UNDEFINED.
};

namedExpression(10);
globalExpression();

Вы можете проверить декларацию функции, тест выражения в другом браузере, используя jsperf Test Runner


Классы функций конструктора ES5: Объекты функций, созданные с помощью Function.prototype.bind

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

function Shape(id) { // Function Declaration
    this.id = id;
};
    // Adding a prototyped method to a function.
    Shape.prototype.getID = function () {
        return this.id;
    };
    Shape.prototype.setID = function ( id ) {
        this.id = id;
    };

var expFn = Shape; // Function Expression

var funObj = new Shape( ); // Function Object
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 );
console.log( funObj.getID() ); // 10

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

ArrowFunction : ArrowParameters => ConciseBody.

const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
console.log( fn(2) ); // Even
console.log( fn(3) ); // Odd

Ответ 11

Я добавляю свой собственный ответ только потому, что все остальные полностью закрыли подъемную часть.

Я задавался вопросом, какой путь лучше уже давно, и благодаря http://jsperf.com теперь я знаю:)

enter image description here

Объявления функций быстрее, и что действительно важно в веб-дизайнере?;)

Ответ 12

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

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

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

  • Когда объявляется объявление функции, тело функции "следует" поэтому, когда тело функции оценивается, переменная немедленно быть привязанным к объекту функции.

  • Когда объявление переменной отображается, инициализация не следовать, но "оставлен". Переменная инициализируется undefined в начале тела функции и будет назначен значение в исходном месте в коде. (На самом деле ему присваивается значение в каждом месте, где происходит объявление переменной с тем же именем.)

Порядок подъема также важен: объявления функций имеют приоритет над объявлениями переменных с тем же именем, а последнее объявление функции имеет приоритет над предыдущими объявлениями с тем же именем.

Некоторые примеры...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

Переменная foo поднимается в начало функции, инициализируется до undefined, так что !foo равно true, поэтому foo присваивается 10. foo вне области bar не играет никакой роли и нетронутой.

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

Объявления функций имеют приоритет над объявлениями переменных, а последнее объявление функции "прилипает".

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

В этом примере a инициализируется объектом функции, полученным в результате оценки объявления второй функции, а затем назначается 4.

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}}
b();
a // 1

Здесь объявляется объявление функции, объявление и инициализация переменной a. Затем этой переменной присваивается 10. Другими словами: присваивание не присваивается внешней переменной a.

Ответ 13

Первый пример - объявление функции:

function abc(){}

Второй пример - это выражение функции:

var abc = function() {};

Основное различие заключается в том, как они поднимаются (поднимаются и объявляются). В первом примере объявляется объявление всей функции. Во втором примере поднимается только var 'abc', его значение (функция) будет undefined, а сама функция остается в том положении, в котором она объявлена.

Проще говоря:

//this will work
abc(param);
function abc(){}

//this would fail
abc(param);
var abc = function() {}

Чтобы узнать больше об этой теме, я настоятельно рекомендую вам это ссылка

Ответ 14

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

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

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

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

{
    member:function() { /* How do I make "this.member" a named function? */
    }
}

Ответ 15

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

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

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

Используя синтаксис переменных, я могу объявить переменную (по существу, указатель функции) в общем коде и либо назначить тривиальную функцию заглушки, либо установить значение null.

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

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

Ответ 16

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

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

Ответ 17

Greg Answer достаточно хорош, но я все еще хотел бы добавить что-то к нему, что я узнал только сейчас, наблюдая видео Дугласа Крокфорда.

Функциональное выражение:

var foo = function foo() {};

Оператор функции:

function foo() {};

Оператор функции является просто сокращением для оператора var с function значением.

Итак,

function foo() {};

расширяется до

var foo = function foo() {};

Расширяется далее:

var foo = undefined;
foo = function foo() {};

И они оба подняты в верхней части кода.

Screenshot from video

Ответ 18

@EugeneLazutkin дает пример, где он называет назначенную функцию, чтобы иметь возможность использовать shortcut() как внутренняя ссылка на себя. John Resig дает еще один пример - копирование рекурсивной функции, назначенной другому объекту в Изучение расширенного Javascript. Хотя назначение функций свойствам здесь не является строго вопросом, я рекомендую активно пробовать учебник - запустите код, нажав кнопку в правом верхнем углу, и дважды щелкните по коду, чтобы изменить его по своему вкусу.

Примеры из учебника: рекурсивные вызовы в yell():

Тесты выходят из строя, когда исходный объект ниндзя удален. (стр. 13)

var ninja = { 
  yell: function(n){ 
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); 

var samurai = { yell: ninja.yell }; 
var ninja = null; 

try { 
  samurai.yell(4); 
} catch(e){ 
  assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); 
}

Если вы назовете функцию, которая будет вызываться рекурсивно, тесты пройдут. (стр. 14)

var ninja = { 
  yell: function yell(n){ 
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); 

var samurai = { yell: ninja.yell }; 
var ninja = {}; 
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );

Ответ 19

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

var functionOne = function() {
    // Some code
};

и использовать это как конструктор, как в

var one = new functionOne();

то one.constructor.name не будет определено. Function.name является нестандартным, но поддерживается браузерами Firefox, Chrome, других Webkit и IE 9 +.

С

function functionTwo() {
    // Some code
}
two = new functionTwo();

можно получить имя конструктора в виде строки с two.constructor.name.

Ответ 20

Первый (функция doSomething (x)) должен быть частью нотации объекта.

Второй (var doSomething = function(x){ alert(x);}) просто создает анонимную функцию и присваивает ее переменной doSomething. Таким образом doSomething() вызовет функцию.

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

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

function foo() {
    return 3;
}

ECMA 5 (13.0) определяет синтаксис как
Идентификатор функции (FormalParameterList opt) {FunctionBody}

В приведенном выше состоянии имя функции видимо в пределах ее области действия и области ее родителя (иначе это было бы недостижимо).

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

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

// Anonymous function expression
var a = function() {
    return 3;
}

// Named function expression
var a = function foo() {
    return 3;
}

// Self-invoking function expression
(function foo() {
    alert("hello!");
})();

ECMA 5 (13.0) определяет синтаксис как
Идентификатор функции opt (FormalParameterList opt) {FunctionBody}

Ответ 21

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

var objectOne = new functionOne();
console.log(objectOne.__proto__); // prints "Object {}" because constructor is an anonymous function

var objectTwo = new functionTwo();
console.log(objectTwo.__proto__); // prints "functionTwo {}" because constructor is a named function

Ответ 22

Я перечисляю следующие различия:

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

    Взгляните на приведенную ниже функцию:

    function outerFunction() {
        function foo() {
           return 1;
        }
        return foo();
        function foo() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 2
    

    Это происходит потому, что во время выполнения оно выглядит так: -

    function foo() {  // The first function declaration is moved to top
        return 1;
    }
    function foo() {  // The second function declaration is moved to top
        return 2;
    }
    function outerFunction() {
        return foo();
    }
    alert(outerFunction()); //So executing from top to bottom,
                            //the last foo() returns 2 which gets displayed
    

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

    Те же функции, что и функциональные выражения:

    function outerFunction() {
        var foo = function() {
           return 1;
        }
        return foo();
        var foo = function() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 1
    

    Это происходит потому, что во время выполнения он выглядит так:

    function outerFunction() {
       var foo = undefined;
       var foo = undefined;
    
       foo = function() {
          return 1;
       };
       return foo ();
       foo = function() {   // This function expression is not reachable
          return 2;
       };
    }
    alert(outerFunction()); // Displays 1
    
  • Нельзя записывать объявления функций в не-функциональных блоках, например , если, потому что они не будут доступны.

    if (test) {
        function x() { doSomething(); }
    }
    
  • Именованное выражение функции, подобное приведенному ниже, может не работать в браузерах Internet Explorer до версии 9.

    var today = function today() {return new Date()}
    

Ответ 23

В свете аргументов "названные функции отображаются в стеках" современные механизмы JavaScript на самом деле вполне способны представлять анонимные функции.

Начиная с этой записи, V8, SpiderMonkey, Chakra и Nitro всегда ссылаются на именованные функции по их именам. Они почти всегда ссылаются на анонимную функцию по ее идентификатору, если она есть.

SpiderMonkey может определить имя анонимной функции, возвращенной из другой функции. Остальное не может.

Если вы действительно хотите, чтобы ваш итератор и успешные обратные вызовы отображались в трассировке, вы могли бы назвать их тоже...

[].forEach(function iterator() {});

Но по большей части это не стоит подчеркивать.

Жгут проводов (Fiddle)

'use strict';

var a = function () {
    throw new Error();
},
    b = function b() {
        throw new Error();
    },
    c = function d() {
        throw new Error();
    },
    e = {
        f: a,
        g: b,
        h: c,
        i: function () {
            throw new Error();
        },
        j: function j() {
            throw new Error();
        },
        k: function l() {
            throw new Error();
        }
    },
    m = (function () {
        return function () {
            throw new Error();
        };
    }()),
    n = (function () {
        return function n() {
            throw new Error();
        };
    }()),
    o = (function () {
        return function p() {
            throw new Error();
        };
    }());

console.log([a, b, c].concat(Object.keys(e).reduce(function (values, key) {
    return values.concat(e[key]);
}, [])).concat([m, n, o]).reduce(function (logs, func) {

    try {
        func();
    } catch (error) {
        return logs.concat('func.name: ' + func.name + '\n' +
                           'Trace:\n' +
                           error.stack);
        // Need to manually log the error object in Nitro.
    }

}, []).join('\n\n'));

V8

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at e.i (http://localhost:8000/test.js:17:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: j
Trace:
Error
    at j (http://localhost:8000/test.js:20:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: l
Trace:
Error
    at l (http://localhost:8000/test.js:23:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at http://localhost:8000/test.js:28:19
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: n
Trace:
Error
    at n (http://localhost:8000/test.js:33:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: p
Trace:
Error
    at p (http://localhost:8000/test.js:38:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27 test.js:42

SpiderMonkey

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: j
Trace:
[email protected]://localhost:8000/test.js:20:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: l
Trace:
[email protected]://localhost:8000/test.js:23:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
m</<@http://localhost:8000/test.js:28:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: n
Trace:
[email protected]://localhost:8000/test.js:33:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: p
Trace:
[email protected]://localhost:8000/test.js:38:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1

Chakra

func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at e.i (http://localhost:8000/test.js:17:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at j (http://localhost:8000/test.js:20:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at l (http://localhost:8000/test.js:23:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at Anonymous function (http://localhost:8000/test.js:28:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at n (http://localhost:8000/test.js:33:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at p (http://localhost:8000/test.js:38:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)

Нитро

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: j
Trace:
[email protected]://localhost:8000/test.js:20:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: l
Trace:
[email protected]://localhost:8000/test.js:23:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
http://localhost:8000/test.js:28:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: n
Trace:
[email protected]://localhost:8000/test.js:33:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: p
Trace:
[email protected]://localhost:8000/test.js:38:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

Ответ 24

𝗯𝗲𝗹𝗼𝘄 𝗮𝗿𝗲 𝗳𝗼𝘂𝗿 𝗻𝗼𝘁𝗲𝘄𝗼𝗿𝘁𝗵𝘆 𝗰𝗼𝗺𝗽𝗮𝗿𝗶𝘀𝗼𝗻𝘀 𝗯𝗲𝘁𝘄𝗲𝗲𝗻 𝘁𝗵𝗲 𝘁𝘄𝗼 𝗱𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝘁 𝗱𝗲𝗰𝗹𝗮𝗿𝗮𝘁𝗶𝗼𝗻𝘀 𝗼𝗳 𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻𝘀 𝗮𝘀 𝗹𝗶𝘀𝘁𝗲𝗱 𝗯𝗲𝗹𝗼𝘄.

  1. Наличие (объем) функции

Следующее работает, потому что function add() находится в пределах ближайшего блока:

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

Ответ 25

В JavaScript существует два способа создания функций:

  • Объявление функции:

    function fn(){
      console.log("Hello");
    }
    fn();
    

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

    Что вы должны знать, так это то, что функции на самом деле являются объектами в JavaScript; внутри мы создали объект для функции выше и дали ему имя, называемое fn, или ссылка на объект хранится в fn. Функции - объекты в JavaScript; экземпляр функции на самом деле является экземпляром объекта.

  • Функциональное выражение:

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

    JavaScript имеет первоклассные функции, т.е. создает функцию и назначает ее переменной так же, как вы создаете строку или номер и присваиваете ее переменной. Здесь переменной fn присваивается функция. Причиной этого понятия являются функции - объекты в JavaScript; fn указывает на экземпляр объекта указанной выше функции. Мы инициализировали функцию и назначили ее переменной. Он не выполняет функцию и не назначает результат.

Ссылка: Синтаксис объявления функции JavaScript: var fn = function() {} vs function fn() {}

Ответ 26

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

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

functionOne();
var functionOne = function() {
    // Some code
};

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

Во второй строке мы назначаем функцию анонимной функции functionOne.

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

functionOne();
function functionOne() {
   // Some code
}

Ответ 27

О производительности:

Новые версии V8 ввели несколько оптимизаций под капотом, а также SpiderMonkey.

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

Chrome 62.0.3202 Тест Chrome

FireFox 55 Firefox test

Chrome Canary 63.0.3225 Хелловерный тест


Anonymous выражения функций имеют лучшую производительностьв выражении функции Named.


Firefox Firefox named_anonymous Chrome Canary Chrome canary named_anonymous Chrome Chrome named_anonymous

Ответ 28

Они довольно похожи с некоторыми небольшими отличиями, первая - это переменная, которая назначается анонимной функции (Объявление функции), а вторая - обычным способом создания функции в JavaScript (анонимная декларация функции), у обоих есть использование, минусы и профи:

1. Выражение функции

var functionOne = function() {
    // Some code
};

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

Назначить переменную функции, значит нет Подъем, так как мы знаем, что функции в JavaScript могут Hoist, означает, что они могут быть вызваны до того, как они будут объявлены, в то время как переменные должны быть объявлены до получения доступа к ним, поэтому в этом случае мы не можем получить доступ к функции до того, где она была заявлена, и это может быть способ, которым вы пишете свои функции, для функций, возвращающих другую функцию, такая декларация может иметь смысл, также в ECMA6 и выше вы можете назначить это arrow, которая может использоваться для вызова анонимных функций, также этот способ объявления - лучший способ создания функций конструктора в JavaScript.

2. Объявление функции

function functionTwo() {
    // Some code
}

Объявление функции определяет именованную функциональную переменную без требующих назначения переменных. Объявление функций происходит как автономные конструкции и не могут быть вложены в не-функциональные блоки. Полезно думать о них как о братьях и сестрах переменных объявлений. Подобно тому, как объявления переменных должны начинаться с "var", Function Объявления должны начинаться с "функции".

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

Кроме того, если вам нужна дополнительная информация о том, как работает подъем в JavaScript, перейдите по ссылке ниже:

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

Ответ 29

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

Ответ 30

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

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()