Анонимная функция – необузданная мощь JavaScript!

Воскресенье, 10 января 2010 года, 11:36. Напечатано в категориях JavaScript, Кодекс, Оптимизация4

Дарова!
Сначала немного теории с wiki:

Анонимная (безымянная) функция — в программировании особый вид функций, которые объявляются в месте использования и не получают уникального идентификатора для доступа к ним. Обычно при создании они либо вызываются напрямую, либо ссылка на функцию присваивается переменной, с помощью которой затем можно косвенно вызывать данную функцию.

В JavaScript анонимная функция выглядит так

function( /*Переменные, передаваемые в функцию*/ ){
  // Код
};
// Пример
function( x, y ){
  return x+y;
};

В чём отличие от не анонимной функции?

Ни в чём! :P

Ведь в JavaScript все переменные – это ссылки на объекты. А анонимная функция – это такой же простой объект, как и строка! Не понятно? Тогда смотрите следующий код с пояснениями!

// Мы создаём анонимную функцию и она просто существует
// Но к ней нельзя обратиться, и как следствие,
// её нельзя запустить где-либо кроме как в месте объявления
function(a){return '';};
// Мы создаём именованную функцию и можем к ней обратиться
function printAgent(){
  alert( "Ваш userAgent:\n" + navigator.userAgent );
};
// Запускаем её
printAgent();
// Другой вариант создания именованной функции:
// Передеча ссылки на анонимную функцию переменной
var pAgent = function(){
  alert( "Ваш старый userAgent:\n" + navigator.userAgent );
};
// Запускаем её
pAgent();

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

var calc = function( a ){
  return a * a;
};
var res = calc( 9 );
alert( res );

Если можно запускать именованные функнции, значит можно запускать и анонимные функции. По логике это будет так:

var res = function( a ){
  return a * a;
}( 12 );
alert( res );

Работает! Только для запуска таких анонимных функций существует более валидная конструкция, которая запаковывает её в скобки, а именно:

var res = (function( a ){
  return a * a;
})( 14 );
alert( res );

Кстати, внутри такой функции(да и в любой другой) обраузется замечательная штука – новая область определения переменных!
Если мы пишем вот такой код:

<script type="text/javascript">
var newVar = 5;
alert( newVar ); // 5
alert( window.newVar ); // 5
</script>

Здесь наша область определения переменных – window. Всё, что назначается здесь – становится свойствами объекта window. Это не есть хорошо, нам незачем захламлять новыми свойствами такой хороший объект! :P

Для нашего кода будем использовать анонимную область определения переменных – внутри анонимной функции.

(function(){
  var h = 158;
  // Килограммы кода
})();
alert( window.h ); // Нема :P

Мы добились того, чего хотели!

Мы защитили объект window от внеземных вторжений! :P

Лично от себя бы хотел порекомендовать вам использовать такую конструкцию для своего кода:

(function(){
  // Код
})();
Спасибо :)


Комментарии(4)

Riim пишет в воскресенье, 10.01.2010 в 15:07 Ответить
в JavaScript все переменные – это ссылки на объекты

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

Но к ней нельзя обратится, её нельзя запустить

как-то противоречиво, сначала утверждение, что ее нельзя запустить, но чуть ниже она запускается:
(function() {/*....*/})();
Regent пишет в воскресенье, 10.01.2010 в 15:18 Ответить
@Riim, совершенно верно, тот пример, который вы привели - её можно запустить:
(function() {/*....*/})();

Но всё - таки это пояснение
Но к ней нельзя обратится, её нельзя запустить

отностится к этой строчке кода:
function(a){return '';};

Одной простой строчки кода без каких - либо добавлений и исправлений, при запуске которой в её первозданном виде образуется ошибка.
Riim пишет в воскресенье, 10.01.2010 в 19:45 Ответить
Тогда, наверное, лучше поправить так: "Но к ней нельзя обратиться, и как следствие, её нельзя запустить где-либо кроме как в месте объявления".
Regent пишет в воскресенье, 10.01.2010 в 19:54 Ответить
@Riim, спасибо, исправил!
Очень признателен за помощь!
Уведомлять меня о новых комментариях по почте
Для корректной работы отправки комментариев необходимо включить JavaScript
Либо скачать новый нормальный браузер