Как вызвать функцию в теле программы

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

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

Давайте напишем простую функцию, которая возвращает массив из трех элементов — текущего значения this и двух аргументов, переданных в функцию.

function makeArray(arg1, arg2)

Самый распространенный способ: глобальный вызов

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

C# — Методы. Уроки для маленьких и тупых #9.

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 , поэтому имеет смысл предупреждать их возникновение заранее.

Источник: habr.com

Синтаксис функций в С++

В языках C и C++, функции должны быть объявлены до момента их вызова. Вы можете объявить функцию, при этом функция может возвращать значение или — нет, имя функции присваивает программист, типы данных параметров указываются в соответствии с передаваемыми в функцию значениями. Имена аргументов, при объявления прототипов являются необязательными:

int sum(int , int ); // тот же прототип функции

Иногда, объявление функции называют определением функции, хотя это не одно и то же.

Определение функций

returnDataType functionName( dataType argName1, dataType argName2, . dataType argNameN) < // тело функции >

Рассмотрим определение функции на примере функции sum .

// определение функции, которая суммирует два целых числа и возвращает их сумму int sum(int num1, int num2)

В языках C и C++, функции не должны быть определены до момента их использования, но они должны быть ранее объявлены. Но даже после всего этого, в конце концов, эта функция должна быть определена. После этого прототип функции и ее определение связываются, и эта функция может быть использована.

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

// объявление функции суммирования int sum(int, int); // определение функции суммирования int sum(int num1, int num2)

Вызов функций

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

funcName( arg1, arg2, . );

  • funcName — имя функции;
  • arg1..2 — аргументы функции (значения или переменные)

Примечание: функции могут не иметь параметров, тогда в круглых скобочках ничего писать не надо.
// вызов функции синуса sin( 60 );

Вызов функции выполняется записью её имени, а затем круглых скобочек () . Если функция принимает аргументы, то в круглых скобках передаются аргументы, в порядке, указанном в объявлении функции. Подробно про функции, читайте статью: Функции в С++.

Источник: cppstudio.com

Функции

Аннотация: Функции – это основные единицы построения программ при процедурном программировании на языке Си++. Правила их записи, вызова и передачи параметров.

Читайте также:
Через какую программу можно пробить человека

Вызов функций

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

Программа на языке Си++ состоит, по крайней мере, из одной функции – функции main . С нее всегда начинается выполнение программы. Встретив имя функции в выражении, программа вызовет эту функцию , т.е. передаст управление на ее начало и начнет выполнять операторы . Достигнув конца функции или оператора return – выхода из функции , управление вернется в ту точку, откуда функция была вызвана, подставив вместо нее вычисленный результат.

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

// функция sqrt с одним аргументом – вещественным числом двойной точности, // возвращает результат типа double double sqrt(double x); // функция sum от трех целых аргументов // возвращает целое число int sum(int a, int b, int c);

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

double x = sqrt(3) + 1; sum(k, l, m) / 15;

Если функция не возвращает никакого результата, т.е. она объявлена как void , ее вызов не может быть использован как операнд более сложного выражения, а должен быть записан сам по себе:

func(a,b,c);

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

int sum(int a, int b, int c)

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

Аргументы a , b и c называются формальными параметрами. Это переменные, которые определены в теле функции (т.е. к ним можно обращаться только внутри фигурных скобок). При написании определения функции программа не знает их значения. При вызове функции вместо них подставляются фактические параметры – значения, с которыми функция вызывается. Выше, в примере вызова функции sum , фактическими параметрами ( или фактическими аргументами ) являлись значения переменных k , l и m .

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

Первое, что мы делаем в теле функции — объявляем внутреннюю переменную result типа целое. Переменные, объявленные в теле функции , также называют локальными. Это связано с тем, что переменная result существует только во время выполнения тела функции sum . После завершения выполнения функции она уничтожается – ее имя становится неизвестным, и память , занимаемая этой переменной, освобождается.

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

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

int k = 2; int l = 3; int m = 5; int s = sum(k, l, m);

Источник: intuit.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru