Объявление функции в javascript. Функциональное программирование

JavaScript function позволяют организовать скрипты и упрощают повторное использование кода. Вместо того чтобы создавать длинные фрагменты кода, разбросанные по всей HTML-странице , скрипты организуются в логические группы.

Объявление и вызов функции JavaScript

Синтаксис функции JavaScript выглядит следующим образом:

function ""имя"" (""аргумент1"", ""аргумент2"", ""аргумент3"" ...) { ""операторы"" return ""значение"" }

Имя определяет, как мы будем называть функцию при ее вызове. Аргументы задают значения, которые передаются функции для обработки. Раздел операторы представляет собой тело функции, которая выполняет обработку. Необязательный оператор return позволяет вернуть значение.

В следующем примере показана функция, определяемая в разделе HTML-страницы и вызываемая в разделе :

function sayHello() { alert("Привет!"); } sayHello();

Передача аргументов в функцию

В приведенном выше примере (script type text JavaScript function ) функции не передается никакие аргументы. Обычно функция предназначена для выполнения каких-либо действий с несколькими аргументами:

Простой пример функции JavaScript function sayHello(day, month) { alert("Привет! Сегодня " + day + " " + month); } sayHello("24", "Июля"); sayHello ("1", "Августа"); sayHello ("24", "Мая");

В этом примере JavaScript callback function вызывается несколько раз, принимая аргументы, которые затем используются для создания строки, отображаемой в диалоговом окне. Чтобы сделать это без функции, нужно было бы повторить скрипт в разделе три раза. Очевидно, что использование функции является более эффективным подходом.

Возврат значения из функции

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

Простой пример функции JavaScript var result = addValues(10, 20) document.write ("Результат = " + result);

В приведенном выше примере мы передаем в функцию addValues значения 10 и 20 . Функция addValues складывает эти два значения и возвращает результат. Оператор return присваивает результат переменной result, которая затем используется для создания строки, выводимой на HTML-странице .

Вызов JavaScript function может быть выполнен в разных местах. Например, не обязательно присваивать результат в качестве значения переменной. Можно использовать его непосредственно в качестве аргумента при вызове document.write .

Важно отметить, что функция может возвращать только одно значение:

Простой пример функции JavaScript function addValues(value1, value2) { return value1 + value2; } document.write ("Результат = " + addValues(10, 20)); JavaScript onclick function также могут использоваться в условных выражениях. Например: Простой пример функции JavaScript function addValues(value1, value2) { return value1 + value2; } if (addValues(10, 20) > 20) { document.write ("Результат > 20"); } else { document.write ("Результат < 20"); }

Где размещать объявления функций

Есть два места, в которых рекомендуется размещать объявления JavaScript function return: внутри раздела HTML-документа или во внешнем файле .js . Наиболее предпочтительным местом считается второй вариант, так как он обеспечивает наибольшую гибкость.

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

Перевод статьи «Understanding JavaScript Functions » был подготовлен дружной командой проекта .

Хорошо Плохо

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

В JavaScript функция является значением, поэтому её можно присваивать переменным, элементам массива, свойствам объектов, передавать в качестве аргумента функциям и возвращать в качестве значения из функций.

Объявление и вызов функции

Существует три способа объявления функции: Function Declaration, Function Expression и Named Function Expression.

Function Declaration (сокращённо FD) – это "классическое" объявление функции. В JavaScript функции объявляются с помощью литерала функции. Синтаксис объявления FD:

Литерал функции состоит из следующих четырёх частей:

  • Ключевое слово function .
  • Обязательный идентификатор, определяющий имя функции. В качестве имени функции обычно выбирают глагол, т. к. функция выполняет действие.
  • Пара круглых скобок вокруг списка из нуля или более идентификаторов, разделяемых запятыми. Данные идентификаторы называются параметрами функции.
  • Тело функции, состоящее из пары фигурных скобок, внутри которых располагаются инструкции. Тело функции может быть пустым, но фигурные скобки должны быть указаны всегда.
  • Простой пример:

    Function sayHi() { alert("Hello"); }

    Встречая ключевое слово function интерпретатор создаёт функцию и затем присваивает ссылку на неё переменной с именем sayHi (переменная с данным именем создаётся интерпретатором автоматически).

    Обратившись к переменной sayHi можно увидеть, что в качестве значения там находится функция (на самом деле ссылка на неё):

    Alert(sayHi); // function sayHi() { alert("Hello"); }

    Function Expression (сокращённо FE) – это объявление функции, которое является частью какого-либо выражения (например присваивания). Синтаксис объявления FE:

    Function (параметры) { инструкции }

    Простой пример:

    Var sayHi = function () { alert("Hello"); };

    Функцию FE иначе ещё называют "анонимной функцией ".

    Named Function Expression (сокращённо NFE) – это объявление функции, которое является частью какого-либо выражения (например присваивания). Синтаксис объявления NFE:

    Function идентификатор (параметры) { инструкции }

    Простой пример:

    Var sayHi = function foo() { alert("Hello"); };

    Объявления FE и NFE обрабатываются интерпретатором точно так же, как и объявление FD: интерпретатор создаёт функцию и сохраняет ссылку на неё в переменной sayHi.

    Программный код, расположенный в теле функции, выполняется не в момент объявления функции, а в момент её вызова. Для вызова функции используется оператор () (вызов функции):

    Function sayHi() { alert("Hello"); } var sayHi2 = function () { alert("Hello2"); }; var sayHi3 = function foo() { alert("Hello3"); }; sayHi(); // "Hello" sayHi2(); // "Hello2" sayHi3(); // "Hello3"

    Разница между представленными тремя объявлениями заключается в том, что функции, объявленные как FD, создаются интерпретатором до начала выполнения кода (на этапе анализа), поэтому их можно вызывать (в той области видимости где они объявлены) до объявления:

    // Вызов функции до её объявления в коде верхнего уровня foo(); function foo() { alert("Вызов функции foo() в глобальной области видимости."); // Вызов функции до её объявления в области видимости функции bar(); function bar() { alert("Вызов функции bar() в области видимости функции."); } }

    Функции, объявленные как FE или NFE, создаются в процессе выполнения кода, поэтому их можно вызывать только после того как они объявлены:

    // sayHi(); // Ошибка. Функция sayHi ещё не существует var sayHi = function () { alert("Hello!"); }; sayHi();

    Функции, объявленные внутри блока, находятся в блочной области видимости:

    // foo(); // Ошибка. Функция не объявлена. { foo(); // 1 function foo() { console.log(1); } } foo(); // Ошибка. Функция не объявлена.

    В отличие от FE, функция, объявленная как NFE, имеет возможность обращаться к себе по имени при рекурсивном вызове. Имя функции доступно только внутри самой функции:

    (function sayHi(str) { if (str) { return; } sayHi("hi"); // Имя доступно внутри функции })(); sayHi(); // Ошибка. Функция не объявлена

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

    Функция обратного вызова – это функция, которая передаётся в качестве аргумента другой функции для последующего её вызова.

    Функции обратного вызова часто используются, в качестве обработчиков событий.

    Ниже приведён пример функции, принимающей в качестве своего аргумента ссылку на другую функцию для её последующего вызова:

    Function foo(callback) { return callback(); } foo (function() { alert("Hello!"); });

    Этот пример наглядно демонстрирует принцип действия обратного вызова.

    Как создать функцию в JavaScript ? Такой вопрос достаточно распространён среди начинающих программистов. И эта статья написана как раз для таких новичков. Для начала необходимо разобраться с вопросом: а что такое функция? Давайте с этого и начнём.

    Вы должны помнить из школы, что такое функция. Если нет, то напоминаю. У функции есть определённые параметры, которыми она манипулирует, и возвращает результат. Например, функция y = 2 * x +5. Здесь мы можем задать x = 3, а в ответ получим y = 11. Вот это пример функции из математики. Абсолютно аналогичные функции и в JavaScript , только тут функцией может быть не просто какое-то вычисление какого-то выражения, а всё, что угодно.

    Давайте для начала создадим функцию, которая 3 раза выводит сообщение "Привет ".


    function hello() {
    alert("Привет");
    alert("Привет");
    alert("Привет");
    }
    hello();

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

    Когда функция написана, то необходимо поставить закрывающую фигурную скобку. На следующей строке мы вызываем функцию hello() . Надеюсь, Вам стало понятно, что такое функция. Возможно, что некоторые из Вас спросят: "А какие преимущества? Ведь мы могли бы просто написать три раза alert() и результат был бы тот же". Вы правы, и так и нужно поступать, если Вам нужно использовать этот код всего один раз. А представьте, что Вам это нужно 3, 4 или большее число раз. Разумеется, неудобно писать постоянно этот повторяющийся код. Гораздо проще написать одно слово hello(). Согласны? Думаю, что да. В конце статьи я, исходя из этого, сделаю один очень важный вывод, поэтому дочитайте её до конца.

    Теперь поговорим о функциях с параметрами. Давайте создадим один из таких примеров (буду писать сразу функцию и её вызов, без тега ).

    Function sum (x, y) {
    var sum = x + y;
    document.write(sum);
    }
    sum(5, 4);

    Код достаточно прозрачный, однако, давайте прокомментирую. Опять ключевое слово function , потом название функции (в данном случае, пусть будет sum ). Внутри скобок указал два параметра, которые требуются (x и y ). Внутри функции я создаю ещё одну переменную sum (это совершенно нормально называть переменные и функции одинаково), которой присваиваю сумму x и y (которые были переданы). И затем вывожу в окно браузера полученный результат. После функции вызываю её, передав параметры 5 и 4 . Вы можете проверить, и увидите в окне браузера - 9 .

    И, напоследок, скажу о возвращаемых значениях. В примере выше мы результат сразу печатали, однако, для данной функции будет наиболее логично ничего не печатать, а возвратить результат. А что дальше с ним делать - это уже другой вопрос. Давайте перепишем функцию так:

    Function sum(x, y) {
    var sum = x + y;
    return sum;
    }
    var z = sum(4, 5) + sum(1,-3);
    document.write(z);

    Обратите внимание на ключевое слово return . Оно возвращает результат (в нашем случае - сумму двух чисел). Таким образом, sum(4,5) возвращает 9 . Это число мы складываем с результатом работы функции sum(1, -3) , то есть -2 . В итоге мы получим 7 . И только потом печатаем результат в браузере.

    Надеюсь, Вы оценили возможности функций, поэтому создавать и использовать функции в JavaScript надо обязательно. И сейчас я сделаю один важный вывод, принцип, которому надо всегда следовать: любой повторяющийся код - необходимо выделять в отдельную функцию . Если у Вас 20 раз выводится одинаковые 5 строк (к примеру), то необходимо эти 5 строк выделить в отдельную функцию. Тем самым Вы вместо 100 строк (20 раз * 5 строк), напишите только 20 строк, да ещё и более понятных (название функции - это гораздо проще, чем 5 строк кода). Хочется сказать, что если этому правилу не следовать, то размер программы может увеличиться в десятки, а, может, и в сотни раз.

    Советую Вам потренироваться и, например, создать функции всех основных математических операций (сложение, вычитание, умножение и деление).

    В этой главе:

    Функции – это один из основных способов объединения операторов в логически связанные блоки. В языке JavaScript функция представляет собой группу выражений, служащих для выполнения какой-либо определенной задачи, объединенных под общим именем.

    В отличие от большинства других языков программирования, JavaScript не делает различий между собственно функциями и процедурами. Подобно функциям, процедуры так же представляют собой программные блоки. Однако результаты выполнения процедур непосредственно сказываются на выполнении программы, в то время как функции должны возвращать значения. С этой точки зрения функции JavaScript можно рассматривать и как процедуры.

    Определение и вызов функций

    Прежде, чем вызывать и использовать функцию, ее надо определить. Определение функций в JavaScript имеет следующий синтаксис:

    Function ИмяФункции (аргументы) { блок выражений }

    Таким образом, функция состоит из следующих частей, предваряемых ключевым словом function:

    • идентификатора, определяющего имя функции;
    • списка аргументов, заключенного в круглые скобки и разделенного запятыми;
    • операторов JavaScript, заключенных в фигурные скобки. Эти операторы могут включать вызовы других функций или даже самой этой функции (рекурсия).

    В простейшем случае аргументы могут отсутствовать, а блок операций моет быть представлен единственным оператором:

    Function MyFirstFunc () { var MyMessage="Это – моя функция!"; alert(MyMessage); }

    Здесь мы определили функцию, которая будет выдавать окно с сообщением «Это – моя функция!». Следует заметить, что даже если функция не принимает никаких аргументов, она все равно должна иметь пару круглых скобок после своего названия.

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

    Но чаще всего функции все-таки принимают какие-либо значения в качестве своих аргументов. Возьмем для примера ранее рассмотренный блок, вычисляющий список чисел, на которые 100 делится без остатка. Если этот блок вынести в отдельную функцию, то можно будет использовать его для того, чтобы выводить список делителей для любого числа. Для этого нам потребуется всего один аргумент, который и будет определять число, для которого нам нужно получить такой список:

    Function remainder_free(j) { var i=0; while (i function
    То есть вызов makeArray("one", "two"); равносилен вызову window.makeArray("one", "two"); .

    Меня печалит тот факт, что этот способ вызова функций наиболее распространен, ведь он подразумевает наличие глобальной функции. А мы все знаем, что глобальные функции и переменные - не самый хороший тон в программировании. Особенно это справедливо для JavaScript. Избегайте глобальных определений, и не пожалеете.

    Правило вызова функций №1: Если функция вызывается напрямую, без указания объекта (например, myFunction()), значением this будет глобальный объект (window в случае исполнения кода в браузере).

    Вызов метода Давайте создадим простой объект и сделаем makeArray его методом. Объект объявим с помощью литеральной нотации, а после вызовем наш метод:
    // создаем объект var arrayMaker = { someProperty: "какое-то значение", make: makeArray }; // вызываем метод make() arrayMaker.make("one", "two"); // => [ arrayMaker, "one", "two" ] // альтернативный синтаксис, используем квадратные скобки arrayMaker["make"]("one", "two"); // => [ arrayMaker, "one", "two" ]
    Видите разницу? Значение this в этом случае - сам объект. Почему не window , как в предыдущем случае, ведь объявление функции не изменилось? Весь секрет в том, как передаются функции в JavaScript. Function - это стандартный тип JavaScript, являющийся на самом деле объектом, и как и любой другой объект, функции можно передавать и копировать. В данном случае, мы как бы скопировали всю функцию, включая список аргументов и тело, и присвоили получившийся объект свойству make объекта arrayMaker . Это равносильно такому объявлению:
    var arrayMaker = { someProperty: "Какое-то значение"; make: function (arg1, arg2) { return [ this, arg1, arg2]; } };
    Правило вызова функций №2: В функции, вызванной с использованием синтаксиса вызова метода, например, obj.myFunction() или obj["myFunction"]() , this будет иметь значение obj .

    Непонимание этого простого, в общем-то, принципа часто приводит к ошибкам при обработке событий:
    function buttonClicked(){ var text = (this === window) ? "window" : this.id; alert(text); } var button1 = document.getElementById("btn1"); var button2 = document.getElementById("btn2"); button1.onclick = buttonClicked; button2.onclick = function(){ buttonClicked(); };
    Щелчок по первой кнопке покажет сообщение «btn1» , потому что в данном случае мы вызываем функцию как метод, и this внутри функции получит значение объекта, которому этот метод принадлежит. Щелчок по второй кнопке выдаст «window» , потому что в этом случае мы вызываем buttonClicked напрямую (т.е. не как obj.buttonClicked()). То же самое происходит, когда мы назначаем обработчик события в тэге элемента, как в случае третьей кнопки. Щелчок по третьей кнопке покажет то же самое сообщение, что и для второй.

    При использовании библиотек вроде jQuery думать об этом не надо. jQuery позаботится о том, чтобы переписать значение this в обработчике события так, чтобы значением this был элемент, вызвавший событие:
    // используем jQuery $("#btn1").click(function() { alert(this.id); // jQuery позаботится о том, чтобы "this" являлась кнопкой });
    Каким образом jQuery удается изменить значение this ? Читайте ниже.

    Еще два способа: apply() и call() Логично, что чем чаще вы используете функции, тем чаще вам приходится передавать их и вызывать в разных контекстах. Зачастую возникает необходимость переопределить значение this . Если вы помните, функции в JavaScript являются объектами. На практике это означает, что у функций есть предопределенные методы. apply() и call() - два из них. Они позволяют переопределять значение this:
    var car = { year: 2008, model: "Dodge Bailout" }; makeArray.apply(car, [ "one", "two" ]); // => [ car, "one", "two" ] makeArray.call(car, "one", "two"); // => [ car, "one", "two" ]
    Эти два метода очень похожи. Первый параметр переопределяет this . Различия между ними заключаются в последющих аргументах: Function.apply() принимает массив значений, которые будут переданы функции, а Function.call() принимает аргументы раздельно. На практике, по моему мнению, удобнее применять apply() .

    Правило вызова функций №3: Если требуется переопределить значение this , не копируя функцию в другой объект, можно использовать myFunction.apply(obj) или myFunction.call(obj) .

    Конструкторы Я не буду подробно останавливаться на объявлении собственных типов в JavaScript, но считаю необходимым напомнить, что в JavaScript нет классов, а любой пользовательский тип нуждается в конструкторе. Кроме того, методы пользовательского типа лучше объявлять через prototype , который является свойством фукции-конструктора. Давайте создадим свой тип:
    // объявляем конструктор function ArrayMaker(arg1, arg2) { this.someProperty = "неважно"; this.theArray = [ this, arg1, arg2 ]; } // объявляем методы ArrayMaker.prototype = { someMethod: function () { alert("Вызван someMethod"); }, getArray: function () { return this.theArray; } }; var am = new ArrayMaker("one", "two"); var other = new ArrayMaker("first", "second"); am.getArray(); // => [ am, "one", "two" ]
    Важным в этом примере является наличие оператора new перед вызовом функции. Если бы не он, это был бы глобальный вызов, и создаваемые в конструкторе свойства относились бы к глобальному объекту. Нам такого не надо. Кроме того, в конструкторах обычно не возвращают значения явно. Без оператора new конструктор вернул бы undefined , с ним он возвращает this . Хорошим стилем считается наименование конструкторов с заглавной буквы; это позволит вспомнить о необходимости оператора new .

    В остальном, код внутри конструктора, скорее всего, будет похож на код, который вы написали бы на другом языке. Значение this в данном случае - это новый объект, который вы создаете.

    Правило вызова функций №4: При вызове функции с оператором new , значением this будет новый объект, созданный средой исполнения JavaScript. Если эта функция не возвращает какой-либо объект явно, будет неявно возвращен this .

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

    Просмотров