JS ++ | Функции

Опубликовано: 10 Апреля, 2022

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

Note: This tutorial does not cover external functions in JS++. An external function is declared with the function keyword and returns an external type. We will examine external functions and external types in Chapter 9. (To preview, an external type is one which isn’t a JS++ type; usually, these will be JavaScript types.) This tutorial examines internal JS++ functions. Internal functions are not declared using the function keyword, and can return any type.

Declaring and calling functions

Прежде чем мы сможем использовать функцию для чего-либо, мы должны ее объявить. Итак, начнем с того, что посмотрим, как объявляются функции. Создайте новую папку и назовите ее «Функции». Затем создайте новый файл и назовите его «Functions.jspp». Напишите следующий код:

 внешний $;

string getFavoriteAnimalString (строковое животное) {
    return "Мое любимое животное" + животное;
}

Save Functions.jspp to your Functions folder. The code we have written declares a function named getFavoriteAnimalString. This name is appropriate, because the function’s purpose is to return a string which states one’s favourite animal. That task is accomplished by the return statement in the function’s body (the part within the curly braces): the return statement evaluates the expression to the right of the return keyword, and then sends the evaluated expression back to the function’s caller (where it might be assigned to a variable, for example). Since the purpose of getFavoriteAnimalString is to return a string, we can say that the function’s return type is string, and we specify this by writing string to left of the function’s name.

Just as the output of getFavoriteAnimalString will be a string, it also takes a string input. To compose the string which reports one’s favourite animal, the function needs to know which particular animal is one’s favourite. It receives this input information via the string parameter named animal, which we write inside the parentheses to the right of the function’s name. When at a later stage of our program we call getFavoriteAnimalString to get it to execute, we will pass a particular string into its input parameter: the particular string we pass it will be the function’s argument.

Примечание. Различие между параметром (ами) функции и ее аргументом (ами) может сбивать с толку. Чтобы уточнить, параметр - это переменная, записанная при объявлении функции. Тип параметра указывает, какой тип ввода принимает функция. Напротив, аргумент - это фактическое значение, переданное функции в качестве входных данных при вызове функции. Аргумент становится значением переменной параметра.

Before we call getFavoriteAnimalString, let’s set up an HTML document which we will use to display the result. Make a second file named “Functions.html” and write in the following:

<!DOCTYPE html>
<title>Functions program</title>
<body>
<p id="content"></p>
<script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="Functions.jspp.js"></script>
</body>
</html>

Save Functions.html to your Functions folder. Now go back to Functions.jspp and write in the following, below the code where you declared getFavoriteAnimalString:

string favoriteAnimalString = getFavoriteAnimalString("cat");
$("#content").text(favoriteAnimalString);

On the first of these new lines, we call getFavoriteAnimalString, passing it the string “cat” as its argument. This function call returns the string “My favorite animal is the cat”, and we assign this string to the variable favoriteAnimalString. On the second line, we use jQuery to select the “content” element of Functions.html and to set its text to the value of favoriteAnimalString. Compile Functions.jspp and then open Functions.html in a browser. If everything has worked, your document should display “My favorite animal is the cat”.

Returning from a function

In our example, getFavoriteAnimalString returns a string. In general, however, a JS++ function can return any valid type, so long as the value returned belongs to the return type specified to the left of the function’s name in the declaration.

A function cannot have more than one return type, but it need not return anything at all. If a function does not return anything, it should be declared with the void keyword:

void displayFavoriteAnimalString(string animal) {
    string favoriteAnimalString = "My favorite animal is the " + animal;
    $("#content").text(favoriteAnimalString);
}

A void function can be declared without using a return statement (as in the example above), or it can be declared with the statement return; which doesn’t evaluate or return any expression.

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

Параметры

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

 void displayFavoriteAnimalIfLucky (string animal, int number) {
    string favouriteAnimalString = "Мое любимое животное" + животное;
    if (number == 7) {
        $ ("# содержание"). текст (любимаяАнимальнаяСтрока);
    }
}

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

Рекурсивные функции

Рекурсивная функция - это функция, которая может вызывать сама себя во время выполнения. Вот известный пример рекурсивной функции:

 int factorial (int input) {
    if (input <= 1) {
        возвратный ввод;
    } еще {
        вернуть вход * факториал (вход - 1);
    }
}

The purpose of factorial is to calculate and return the factorial of the input parameter. For example, if we call factorial with an input of 5, it will return 120.

factorial illustrates a general structure that is common to many recursive functions. The function handles two sorts of cases differently, depending on the value of the input argument. In the base case, the value of the argument means that the function’s task can be accomplished easily, with little or no further work required. The function therefore returns without any need to call itself. In the recursive case, by contrast, significant further work is required. To accomplish this, the function in some way simplifies or reduces that further work, which involves calling itself with a modified input value. The modified input value will be closer to the value needed to qualify for a base case.

The base case for factorial comes when the input argument is less than or equal to 1. In this case, the function simply returns input. If input is greater than 1, by contrast, the functions returns input * factorial(input - 1). Thus factorial will repeatedly call itself, with the value of input decreasing by 1 with each recursive call. When factorial calls itself with an input value of 1, that particular recursive call returns, which then enables each of the previous recursive calls to return.

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

Перегрузка

JS++ allows functions to be overloaded. Overloading consists in declaring two functions with the same name, but with different parameter lists. For example, we might overload a function named displayFavoriteAnimalString as follows:

void displayFavoriteAnimalString(string animal) {
string favoriteAnimalString = “My favorite animal is the ” + animal;
$(“#content”).text(favoriteAnimalString);
}

void displayFavoriteAnimalString(string firstAnimal, string secondAnimal) {
string favoriteAnimalString = “My favorite animals include the ” + firstAnimal + ” and the ” + secondAnimal;
$(“#content”).text(favoriteAnimalString);
}

Компилятор позволяет таким образом объявлять две функции с одним и тем же именем из-за разницы в их списках параметров: первая функция принимает один строковый параметр, а вторая функция - два. Это различие означает, что когда вы вызываете одну из двух функций, нет двусмысленности относительно того, что имеется в виду: если вы указываете один строковый аргумент, то это должна быть первая функция, а если вы предоставляете два строковых аргумента, то это должна быть вторая .

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

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

Обратные вызовы и функциональные выражения

Рассмотрим следующий код:

 внешний $;
int (int, int) processNumbers = int (int a, int b) {
    вернуть a + b;
};

If you look carefully at this syntax (and do take note of the trailing semi-colon!), you will see that it isn’t the normal syntax of a function declaration. Rather, what we have here is a variable assignment. The variable is named processNumbers, and its type is specified by the code to the left of the name: int(int, int). This is a callback type. A variable of this type can take a function as its value. However, the range of functions which the variable can take is restricted to those whose parameters and return type match those specified by the callback type. So given that processNumbers has the callback type int(int, int), a function can be assigned to processNumbers only if it takes two int parameters and returns an int.

Код справа от знака «=» назначает выражение функции для обработки чисел. Выражение функции отличается от объявления функции тем, что оно оценивает значение (выраженную функцию). Это означает, что выражение функции может использоваться (как здесь) в присвоении переменной, передаваться в качестве аргумента другой функции или возвращаться из другой функции.

The function assigned to processNumbers is an addition function. It adds the two int arguments together and returns the result. The assignment is fine, since the addition function has the parameters and return type specified by the variable’s callback type: it takes two int parameters and returns an int. Now we can call processNumbers:

int result = processNumbers(3, 4);
$("#content").text(result);

Later on in our program, however, we might decide to assign a different function to processNumbers:

processNumbers = int(int a, int b) {
    return a * b;
};

This assignment is just as valid as the previous one, since the multiplication function assigned also has the correct parameters and return type: it takes two int parameters and returns an int. If we call processNumbers after assigning this new function to it, the result will differ from the one returned by our earlier call.