Объявление функций в 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", если они ищут определение функции.
Я знаю, что это нетехнический ответ, но людям труднее читать код, чем компьютеры.