Тарифы Услуги Сим-карты

Javascript необязательные параметры функции. Функциональное программирование

Как создать функцию в 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 строк кода). Хочется сказать, что если этому правилу не следовать, то размер программы может увеличиться в десятки, а, может, и в сотни раз.

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

24 мая 2011 в 01:13 Пять способов вызвать функцию
  • JavaScript
  • Перевод

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

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

Давайте напишем простую функцию, которая возвращает массив из трех элементов - текущего значения this и двух аргументов, переданных в функцию.
function makeArray(arg1, arg2){ return [ this, arg1, arg2 ]; }

Самый распространенный способ: глобальный вызов Новички часто объявляют функции так, как показано в примере выше. Вызвать эту функцию не составляет труда:
makeArray("one", "two"); // => [ window, "one", "two" ]
Погодите. Откуда взялся объект window ? Почему это у нас this равен window ?

В JavaScript, неважно, выполняется ли скрипт в браузере или в ином окружении, всегда определен глобальный объект . Любой код в нашем скрипте, не «привязанный» к чему-либо (т.е. находящийся вне объявления объекта) на самом деле находится в контексте глобального объекта. В нашем случае, makeArray - не просто функция, «гуляющая» сама по себе. На самом деле, makeArray - метод глобального объекта (в случае исполнения кода в браузере) window . Доказать это легко:
alert(typeof window.methodThatDoesntExist); // => undefined alert(typeof window.makeArray); // => 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 , поэтому имеет смысл предупреждать их возникновение заранее.

В этой главе:

Функции – это один из основных способов объединения операторов в логически связанные блоки. В языке 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