scripts

среда, 7 августа 2013 г.

Немного о JavaScript. Функции.

Функции - это объекты, которые могут вызываться (выполняться). Самая важная особенность функций в том, что они образуют собственные области видимости. Причем в JavaScript только через функцию возможно задать область видимости. Если переменная не входит ни в какую функцию, то она будет глобальной.
JavaScript удивительный язык. Функции в JavaScript - это базис, понимание которого особенно важно. Конечно я в институте изучал по программе C и C++ - там тоже есть понятие функции, но не стоит смешивать мух и котлеты. Вообще хорошо бы опустошить свой "сосуд" и подойти к изучению функций JavaScript с чистого листа, не используя полученные представления из C и C++.
Функции - это данные, их можно хранить в переменных, объектах и массивах, передавать в качестве аргументов и возвращать в качестве результата. Конечно трудно в небольшой статье глубоко раскрыть работу с функциями в JavaScript, но основные моменты я попытаюсь освятить и дать пищу для размышлений.

Функция - выражение

   Именованная функция-выражение
var hello = function hello( name ) {
  console.log('Hello ' + name + '!');
};
   Анонимная функция
var hello = function ( name ) {
  console.log('Hello ' + name + '!');
};
Внимание: заключительная точка с запятой обязательна.

Функция-объявление 

function ( name ) {
  console.log('Hello ' + name + '!');
}
Здесь видно, что если бы анонимная функция не присваивалась переменной (такое как раз встречается при использовании функции обратного вызова), то разницы между двумя определениями нет. В этом случае необходимо посмотреть на контекст, в котором определяется функция.
Для функций-объявлений главное запомнить, что эти функции могут появляться только внутри функций или в глобальной области видимости. Они не могут присваиваться переменным или свойствам, так же не могут передаваться в качестве параметров другим функциям. Есть еще одна особенность функций-объявлений - при "подъеме" вместе с именем функции поднимается ее определение (для именованны функций-выражений "поднимается" только имя).
Эх ностальгия, когда то я начинал работать с JavaScript используя в основном функции-объявления как средство структурирования кода (хотя при разработке модулей nodejs использую их довольно часто).

Функции обратного вызова

Здесь как раз используется та особенность, что функции могут передаваться в качестве параметров. В JavaScript многие вещи делаются асинхронно и функции обратного вызова позволяют удобно работать с асинхронностью. При синхронном выполнении программы, необходимо написать набор инструкций, которые выполняться друг за другом. Например, если мы хотим прочитать файлы какой-то директории:
открыть директорию прочитать файлы
Конечно, при таком подходе все понятно, пока директория не будет открыта, файлы не начнут читаться, но минус в том, что выполнение программы приостанавливается, а запрос к файловой системе "стоит" довольно дорого. Как раз благодаря скорости работы асинхронная модель JavaScript позволяет реализовывать высоконагруженные web сервисы.
В асисинхронном варианте этот пример примет такой вид:
до... открыть директорию ( прочитать файлы ) после...
В коде мы указывает интерпритатору, прочитать файлы после окончания открытия директории, при этом выполнение программы не приостанавливается. Очень часто в качестве функции обратного вызова используют анонимную функцию. Приведу пример для nodeJS.
fs.readdir(subdir, function (err, files) {
  if (!err) {
    работа с files
  } else {
    сообщение об ошибке
  }
});
Вот еще пример использование callback функции.
function say (callback) {
  callback();
}
function hi () {
  console.log('Hi!');
}
say(hi);

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

Приватные функции.

Повторюсь, что функции это данные. Значит допустимо объявить функцию внутри функции. Такая внутренняя функция не будет доступна извне, то есть будет приватной.

Рассмотрим такой пример:
function main() {
  function inner() {
    return "inner function.";
  } 
  return "Main function call the " + inner();
}
Вызовем main:

main()
"Main function call the inner function."

Попробуем вызвать inner:
inner()
"inner is not defined"

Чтож, думаю идея понятна, двигаемся дальше.


Self-invoking function. Немедленно вызываемые функции.

Такая функция вызывается немедленно, в точке ее определения.

Вот, кстати, еще вариант применения анонимных функций (помимо callback).

(function () {
  console.log('Function is run.');
}());
Результат:
"Function is run."

В немедленно вызываемые функции можно передавать параметры. Вот довольно распространенный прием.

(function ($) {
  $('#content').append('Hello!');
}(jQuery));

Немедленно вызываемые функции позволяют возвращать значения.

Немедленно вызываемые функции позволяют создавать изолированную область видимости и возвращать публичные методы (шаблон "модуль").

На этом пока все, впереди разговор про замыкания.

Комментариев нет:

Отправить комментарий