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

Возможный дубликат:
Javascript: var functionName = function() {} vs function functionName() {}

Какая разница между этими двумя способами объявления функции?

function someFunc() { ... }

var someFunc = function() { ... }

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

Ответ 1

Я по-разному придерживаюсь мнения большинства людей. Технически этот синтаксис может означать одно и то же для объявления функций в обоих направлениях (Я остаюсь неверным в своем последнем заявлении. Я прочитал сообщение о различиях, почему они технически отличаются, и в конце я добавлю, почему) ; но способ, которым они играют роль в эволюционирующих моделях, массивный. Я бы очень рекомендовал "Javascript: The Good Parts" от Doughlas Crockford.

Но доказать мою мысль тонким и простым способом; вот небольшой пример.

//Global function existing to serve everyone
function swearOutLoud(swearWord) {
    alert("You "+ swearWord);           
}
//global functions' territory ends here

//here is mr. spongebob. He is very passionate about his objects; but he a bit rude.
var spongeBob = {
    name : "squarePants",
    swear : function(swearWord) {
                name = "spongy";
                alert("You "+ swearWord);
                return this;
            }
}

//finally spongebob learns good manners too. EVOLUTION!
spongeBob.apologize = function() {
    alert("Hey " + this.name + ", I'm sorry man!");
    return this;
}


//Ask spongebob to swear and then apologize in one go (CASCADING EFFECT!!)
alert(spongeBob.swear("twit").apologize());

если вы посмотрите на код выше, я объявил функцию с именем swearOutLoud. Который возьмет ругательное слово от любого объекта или вызова и даст вам результат. Он может выполнять операции над любым объектом, используя параметр "this", который передается ему и аргументы.

Однако второе объявление объявляется как атрибут объекта, называемый "spongeBob". Это важно отметить; так как здесь я двигаюсь в направлении поведения, управляемого объектами. Хотя я также поддерживаю "каскадный эффект", когда возвращаю "this", если мне больше нечего возвращать.

Что-то подобное сделано в jquery; и этот каскадный шаблон важен, если вы пытаетесь написать фреймворк или что-то в этом роде. Вы также свяжете его с шаблоном проектирования Builder.

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

Чтобы увидеть каскадное действие, посмотрите на последнее утверждение, в котором вы можете попросить spongebob поклясться и извиниться сразу; даже если извинения были добавлены как атрибут позже.

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

Но это только я! Возьми это или оставь.:)

EDIT:

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

 //success
 swearOutLoud("Damn");

function swearOutLoud(swearWord) {
    alert("You " + swearWord)
}

Над кодом будет работать правильно. Но код ниже не будет.

swear("Damn!");
    var swear = function(swearWord) {
    console.log(swearWord);
}

Ответ 2

Одним из преимуществ использования function someFunc() { ... } является то, что имя функции отображается в отладчике Firebug. Функции, объявленные другим способом (var someFunc = function() { ... }), выглядят как анонимный.

Ответ 3

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

var myObject=new Object();
myObject.someFunc=function() { ... }; 

Ответ 4

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

this.someFunc = function() { ... }
...
someFunc: function() { ... },

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

var someFunc = function someFunc() { ... }

Ответ 5

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

if (document.addEventListener) {
    function addEventListenerTo(target, event, listener) {
        ....
    }
} else if (document.attachEvent) {
    function addEventListenerTo(target, event, listener) {
        ....
    }
} else {
    function addEventListenerTo(target, event, listener) {
        ....
    }
}

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

var fib = memoize(function (n) { 
    if (n < 0) return 0;
    if (n < 2) return 1;
    return fib(n-1) + fib(n-2); 
});

...
// patch the $ library function
if (...) {
    $ = around($, fixArg, fixResult);
}

Ответ 6

Верно, что первая форма:

function test() { }

является более узнаваемым синтаксисом и что вторая форма:

var test = function() { ... }

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

И вы можете сделать и то и другое:

var test = function test() { ... test(); ... }

Это позволяет вам определить рекурсивную функцию во второй форме.

Ответ 7

Когда вы пишете

function Test() {
}

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

Ответ 8

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

Например, если они когда-нибудь захотят ctrl-f найти определение вашей функции, чтобы увидеть, что происходит там, они будут сначала искать someFunc = function() или function someFunc()?

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

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