Объявление функций в JavaScript [дубликат]

91
задан Community 23 May 2017 в 12:10
поделиться

8 ответов

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

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

//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's 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.

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

Чтобы увидеть эффект каскадирования, посмотрите на последнее утверждение, где вы можете попросить Губку Боба выругаться и сразу извиниться; хотя извинение было добавлено в качестве атрибута позже.

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

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

РЕДАКТИРОВАТЬ:

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

 //success
 swearOutLoud("Damn");

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

Приведенный выше код будет работать правильно. Но код ниже не будет.

swear("Damn!");
    var swear = function(swearWord) {
    console.log(swearWord);
}
49
ответ дан 24 November 2019 в 06:52
поделиться

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

14
ответ дан 24 November 2019 в 06:52
поделиться

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

var myObject=new Object();
myObject.someFunc=function() { ... }; 
5
ответ дан 24 November 2019 в 06:52
поделиться

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

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

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

var someFunc = function someFunc() { ... }
5
ответ дан 24 November 2019 в 06:52
поделиться

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

function test() { }

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

var test = function() { ... }

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

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

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

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

2
ответ дан 24 November 2019 в 06:52
поделиться

Другое отличие состоит в том, что в большинстве браузеров последний позволяет определять различные реализации в зависимости от обстоятельств, а первый - нет. Допустим, вам нужна кроссбраузерная подписка на мероприятия. Если вы попытались определить функцию 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);
}
2
ответ дан 24 November 2019 в 06:52
поделиться

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

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

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

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

1
ответ дан 24 November 2019 в 06:52
поделиться

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

function Test() {
}

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

1
ответ дан 24 November 2019 в 06:52
поделиться