Что происходит в JavaScript, когда я использую «традиционное» объявление функции в стиле C? - PullRequest
9 голосов
/ 26 сентября 2010

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

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

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

Мне нравится идея функции как объекта, который можно передавать, как и любую другую переменную.Поэтому я прекрасно понимаю, что делает (2).Она создает функцию и присваивает add (скажем, это в глобальной области видимости, поэтому add - глобальная переменная) указанной функции.Но что происходит, если я использую (1) вместо этого?Я уже знаю, что это имеет значение в порядке выполнения: если я использую (1), тогда я могу сослаться на add() перед точкой в ​​коде, где определено add(), но если я использую (2), тогда я долженназначьте мою функцию на add, прежде чем я смогу начать ссылаться на add().

Является ли (1) просто ярлыком для (2), хотя тот, который ведет себя как другие языки стиля C, позволяяопределить функцию «ниже» точки, в которой она используется?Или это внутренне другой тип функции?Что более «в духе» JavaScript (если это не слишком расплывчатый термин)?Вы бы ограничились тем или иным, и если да, то каким?

Ответы [ 2 ]

6 голосов
/ 26 сентября 2010

Похоже, вам уже известны основные характеристики объявлений функций 1 (1) и выражений функций (2). Также обратите внимание, что в (1) все еще есть локальная переменная с именем add, содержащая значение функции, как в (2):

function hello () {
   alert('Hello World');
}

console.log(typeof hello);  // prints "function"

setTimeout(hello, 1000);    // you can still pass functions around as arguments,
                            // even when using function declarations.

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

Что касается того, какой подход больше соответствует духу JavaScript, я предпочитаю использовать функциональных выражений (2). Для более авторитетного мнения Дуглас Крокфорд перечисляет объявления функций (1) в главе "Плохие детали" в своей популярной книге Хорошие детали 2 .


1 Также известен как операторы функций (см. @ комментарии Тима Дауна ниже).
2 На самом деле, некоторые браузеры могут обрабатывать объявлений функций в if операторах (снова см. Комментарии ниже).
3 JavaScript: Хорошие части - Приложение B: Страница 113.

2 голосов
/ 26 сентября 2010
function foo() {};
foo.toString() //-> "function foo() {}"

var bar = foo;
bar.toString() //-> "function foo() {}"

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

var foo = function() {};
foo.toString() //-> "function () {}"

var bar = foo;
bar.toString() //-> "function () {}"

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

var MyThingy = {
  foo: function() { alert('foo') },
  bar: function() { MyThingy.foo() }
}

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

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