Предисловие
В Ecmascript существует два наиболее часто используемых метода для создания объектов функции, а именно использование выражений функций или использования объявлений функций. В связи с этим спецификация Ecmascript дает понять, что объявления функций всегда должны нести идентификатор, который мы называем именем функции, и выражения функции могут быть опущены. Давайте посмотрим на подробное введение в различия между ними.
Что такое объявление функции?
Объявление функции может определять именованные переменные функции, не присваивая значения переменным. Объявление функции является независимой структурой, которая не может быть вложена в нефункциональные модули. Это можно сравнить с объявлением переменной. Так же, как объявление переменной должно начинаться с «var», объявление функции должно начинаться с «функции».
Например
Функция bar () {return 3;}ECMA 5 (13.0) Синтаксис определения:
function Identifier ( FormalParameterList[opt] ) { FunctionBody }
Имена функций доступны в их собственной области и масштабах (в противном случае функция не будет доступна).
Функция bar () {return 3;} bar () // 3bar // functionЧто такое выражение функции?
Экспрессия функции определяет функцию как часть оператора выражения (обычно назначение переменных). Функции, определенные выражением функции, могут быть названы или анонимны. Выражение функции не может начаться с «функции» (следующие примеры самообладания должны быть заключены в скобки).
Например
// Anonymous Function ExpressionVar a = function () {return 3;} // именованная функция ExpressionVar a = function bar () {return 3;} // самоотдача выражения функции (функция sayshello () {alert ("hello!");}) ();ECMA 5 (13.0) Синтаксис определения:
function Identifieropt ( FormalParameterList[opt] ) { FunctionBody }
(Это определение кажется неполным, потому что оно игнорирует условие: периферическое утверждение является выражением и не начинается с «функции»)
Имена функций (если таковые имеются) недоступны вне сферы действия (по сравнению с объявлением функций).
Так что же такое оператор функции?
Оператор функции иногда является еще одним способом объявления функции. Но Kangax отмечает, что в Mozilla оператор функции является расширением объявления функции, что позволяет использовать оператор объявления функции в любом месте, что позволяет использовать операторы. Тем не менее, оператор функции сейчас не является стандартом, поэтому его не рекомендуется использовать в разработке продукта.
Давайте начнем с некоторых небольших тестов. Угадайте, что появится в следующих ситуациях?
Вопрос 1:
function foo () {function bar () {return 3; } return bar (); Функция bar () {return 8; }} alert (foo ());Вопрос 2:
function foo () {var bar = function () {return 3; }; вернуть бар (); var bar = function () {return 8; };} alert (foo ());Вопрос 3:
alert (foo ()); function foo () {var bar = function () {return 3; }; вернуть бар (); var bar = function () {return 8; };}Вопрос 4:
function foo () {return bar (); var bar = function () {return 3; }; var bar = function () {return 8; };} alert (foo ());Если ваш ответ не составляет 8, 3, 3 и [Ошибка типа: панель не является функцией], затем продолжите чтение ... (даже если вы правильно отвечаете, вы должны продолжить чтение)
Теперь давайте объясним предыдущий тест.
Вопрос 1 использует декларацию функции, что означает, что они поднимаются ...
Подождите, что такое подъем?
Вот цитата от Бена Черри: «Объявление функции и переменная функции обычно перемещается (« поднят ») в верхнюю часть текущего объема интерпретатора JavaScript».
Когда объявление функции будет продвинуто, весь орган функции будет способствовать соответствующим образом, поэтому код вопроса 1 работает, как это, после объяснения интерпретатора:
// ** Смоделированная последовательность обработки для вопроса 1 ** Функция foo () {// определить планку с помощью панели функции () {return 3; } // Переопределение IT -функции Bar () {return 8; } // возвращать свой призыв return -bar (); // 8} alert (foo ());Тем не менее, нам часто говорят, что код, стоящий за оператором возврата, не может работать ...
Во время выполнения JavaScript есть две концепции: контекст (ECMA 5 разбивает его на лексическую среду, переменную среда и это связывание) и процесс (серия утверждений, называемых последовательно). Когда программа вступает в домен выполнения, объявление вызывает переменную среда. Они отличаются от оператора (например, возврата) и не следуют правилам выполнения операторов.
Будет ли повышено выражение функции?
Это зависит от выражения. Например, первое выражение в вопросе 2:
var bar = function () {return 3;};(Var) слева от равного знака является объявлением переменной. В переменная объявление будет продвигаться, но выражение выражения не будет. Таким образом, когда пропагандируется батончиком, интерпретатор будет инициализирован таким образом: var bar = не определен. Само определение функции не будет способствовать.
(ECMA 5 12.2 Переменные с начальником присваиваются присвоеном экспрессией при выполнении VARIABlestatement, а не при создании переменной.)
Следовательно, код вопроса 2 будет запущен в следующем порядке:
// ** Смоделированная последовательность обработки для вопроса 2 ** Функция foo () {// Объявление для каждой функции выражения var bar = undefined; var bar = не определен; // Первое выражение функции выполняется bar = function () {return 3; }; // Функция, созданная первой экспрессией функции, вызывается return -bar (); // Второе выражение функции недоступно} alert (foo ()); // 3Вы можете сказать, что это можно объяснить, но ответ на вопрос 3 неверен. Я сообщу об ошибке при запуске Firebug.
Сохраните код в HTML -файле и попробуйте запустить его на Firefox. Или бежать в консоли IE8, Chrome или Safari. Очевидно, что консоль Firebug не будет способствовать функции при запуске кода в «глобальном» сфере (на самом деле не глобальной, но уникальной области «Firebug» - просто попробуйте запустить «это окно ==» в консоли Firebug).
Вопрос 3 и Вопрос 1 имеют аналогичную логику. На этот раз функция Foo была продвинута.
Вопрос 4 очень прост, вообще нет улучшения функции ...
Можно сказать, что, но если вообще нет улучшения, TypeError будет «не определен» вместо «Бар, а не функции». В этом примере действительно нет улучшения функций, но есть улучшение переменной. Следовательно, бар объявляется в начале, но его значение не определено. Другие коды выполняются по порядку.
// ** Смоделированная последовательность обработки для вопроса 4 ** Функция foo () {// Объявление для каждой функции выражения var bar = undefined; var bar = не определен; вернуть бар (); // typeError: «Бар не определен» // Ни одно выражение функции не достигнуто} Alert (foo ());На что еще вы должны обратить внимание?
Официальный запрет запрещает использование функционального объявления в нефункциональных модулях (например, если). Тем не менее, все браузеры поддерживают это, но их объяснения разные.
Например, следующий фрагмент кода будет добавлять ошибку в Firefox 3.6, поскольку он интерпретирует объявление функции как оператор функции (см. Выше), поэтому x не определен. Но в IE8, Chrome 5 и Safari 5, функция x будет возвращена (то же самое, что и стандартное объявление функции).
function foo () {if (false) {function x () {}; } return x;} alert (foo ());Видно, что использование объявления функции может вызвать путаницу, так что у него есть какие -либо преимущества?
Вы можете сказать, что объявление функции довольно свободно - если вы попытаетесь использовать функцию перед объявлением, продвижение действительно может исправить порядок, так что функцию можно было правильно вызвать. Но этот вид ослабления не способствует строгому кодированию, и, с долгосрочной перспективы, он, вероятно, будет способствовать, а не предотвратить несчастные случаи. В конце концов, есть причина, по которой программисты расположены заявления в определенном порядке.
Так есть ли другие причины для поддержки выражения функции?
Что вы думаете?
1) Объявление функции ощущается так, как будто имитирует объявления метода в стиле Java, но методы Java не такие, как JavaScript. В JavaScript функции являются живыми объектами со значениями. Методы Java - это только хранение метаданных. Следующие две части кода определяют функцию, но только выражение функции выглядит так, как создается объект.
// Функция объявления функции добавить (a, b) {return a + b}; // function expressionvar add = function (a, b) {return a + b};2) Функция выражения имеет большее использование. Объявление функции может существовать только у сирот как «утверждение». Все, что он может сделать, это создать переменную объекта под текущей областью. Выражение функции, по определению, является частью большой структуры. Если вы хотите создать анонимные функции, добавьте функции в прототипы или используйте функции в качестве свойства других объектов, вы можете использовать экспрессию функции. Всякий раз, когда вы используете расширенные приложения, такие как Curry или Compose, вы используете выражение функции при создании новых функций. Экспрессия функции и функциональное программирование неразделимы.
// Функция ExpressVar SayShello = alert.curry ("Привет!");Есть ли какие -либо недостатки в выражении функции?
Выражение функции создает большинство функций анонимных. Например, следующая функция является анонимной, сегодня является лишь ссылкой на анонимную функцию:
var сегодня = function () {return new date ()}Это будет проблематично? Не в большинстве случаев, но, как отметил Ник Фицджеральд, отладка анонимных функций может быть раздражающей. Он рекомендует использовать названные функции выражения (NFES) в качестве рабочего пространства:
var сегодня = function сегодня () {return new Date ()}Однако, как сказал Асен Божхилов (и документация кангакс), NFE не могут быть выполнены правильно ниже IE9.
в заключение
Случайно расположенное объявление функции вводит в заблуждение и редко (если таковые имеются), и присвоение значений переменным с экспрессией функции не может заменить объявление функции. Но если требуется объявление функции, поместье его в верхней части прицела может уменьшить путаницу. Никогда не ставивайте декларацию функции в оператор IF.
Сказав так много, декларация функции может быть полезно в вашей собственной ситуации. Ничего. Роль догма опасна и часто вызывает бить кода вокруг куста. Что еще более важно, вы понимаете концепцию, чтобы решить, какой метод создавать функцию на основе вашей собственной ситуации. Вышеуказанное - все содержание этой статьи. Я надеюсь, что эта статья будет полезна всем в этом отношении.