Я разделяю мнение большинства присутствующих здесь людей. Технически этот синтаксис может означать одно и то же для объявления функций в обоих направлениях ( Я ошибаюсь в своем последнем утверждении. Я прочитал в сообщении о различиях, почему они технически отличаются друг от друга, и в конце добавлю, почему ) ; но то, как они играют роль в развитии моделей, огромно. Я очень рекомендую "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);
}
Одним из преимуществ использования функции someFunc () {...}
является то, что имя функции отображается в отладчике Firebug. Функции, объявленные другим способом ( var someFunc = function () {...}
), появляются как анонимные .
Фактически, разница в том, что второе объявление дает нам возможность объявлять такие функции, что позволяет иметь функция как свойство объекта:
var myObject=new Object();
myObject.someFunc=function() { ... };
По стилю второй пример более совместим с другими распространенными способами объявления функций, и поэтому можно утверждать, что он более читабелен
this.someFunc = function() { ... }
...
someFunc: function() { ... },
Однако, как также упоминалось, он анонимен, и поэтому имя не появляется при профилировании. Другой способ объявления функции - это лучшее из обоих миров
var someFunc = function someFunc() { ... }
Верно и то, что первая форма:
function test() { }
является более узнаваемым синтаксисом, и что вторая форма:
var test = function() { ... }
позволяет вам управлять областью действия функции (с помощью var; без нее это было бы в любом случае быть глобальным).
И вы даже можете делать и то, и другое:
var test = function test() { ... test(); ... }
Это позволяет вам определять рекурсивную функцию во второй форме.
Другое отличие состоит в том, что в большинстве браузеров последний позволяет определять различные реализации в зависимости от обстоятельств, а первый - нет. Допустим, вам нужна кроссбраузерная подписка на мероприятия. Если вы попытались определить функцию 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);
}
По удобочитаемости я бы сказал, что первое явно лучше. Будущий программист по обслуживанию, даже если предположить, что он достаточно знаком с javascript, чтобы знать многие тонкости, возникающие в этой теме, будет использовать первый формат.
Например, если они когда-нибудь захотят нажать ctrl-f для поиска определения вашей функции, чтобы увидеть, что там происходит, будут ли они сначала искать someFunc = function ()
или функция someFunc ()
?
Кроме того, чтобы сделать это прямо типографским (поскольку мы говорим о читабельности), читатели часто просматривают текст быстро и будут более склонны пропускать строку, начинающуюся с «var», если они ищут определение функции.
Я знаю, что это нетехнический ответ, но это ' Людям труднее читать код, чем компьютерам.
Когда вы пишете
function Test() {
}
, JavaScript действительно создает свойство, которому он назначает объект функции, который после вызова выполнит код, указанный в определении функции. Свойство прикрепляется к объекту , окну
или к объекту, который содержит определение функции.