diff --git a/1-js/2-first-steps/18-function-basics/article.md b/1-js/2-first-steps/18-function-basics/article.md index 2b3d6510..2d6237aa 100644 --- a/1-js/2-first-steps/18-function-basics/article.md +++ b/1-js/2-first-steps/18-function-basics/article.md @@ -130,12 +130,12 @@ alert( userName ); // John, the outer variable is not modified */!* ``` -**Variables declared on the most outer level, not in any function, are called *global*.** +**Variables declared on the script level, outside of any function, are called *global*.** -Please only declare global the variables which have a project-wide importance. Variables needed by specific tasks should reside in the corresponding functions. So to say, global variables are rare in modern projects. +Global variables are visible from any function. They are used to store the data of a project-wide importance. Variables needed by specific tasks should reside in the corresponding functions. [warn header="Attention: implicit global declaration!"] -Without strict mode, for compatibility with the old scripts, it is possible to omit variable declaration: +Without strict mode, for compatibility with the old scripts, it is possible to create a variable by an assignment, without a declaration: ```js //+ run @@ -148,132 +148,147 @@ showMessage(); alert( message ); // Hello ``` -In the code above `message` was not declared. Most probably, the programmer simply forgot to write `let`. +In the code above, most probably, the programmer simply forgot to write `let`. As a result, he created a global variable `message`. -With `"use strict"` there will be an error. But without it, the variable will be created automatically. It will be global. +With `"use strict"` there will be an error. Modern editors and tools for code quality checking like [jshint](http://jshint.com/) allow to see and fix "missed declarations" early while coding. [/warn] Later, after we deal with the basics and data structures, in the chapter [](/closures) we will go deeper in the internals of functions and variables. -## Параметры +## Parameters -При вызове функции ей можно передать данные, которые та использует по своему усмотрению. +We can pass arbitrary data to the function using it's parameters (also called *arguments*) . -Например, этот код выводит два сообщения: +For example, this code shows two messages: ```js //+ run no-beautify -function showMessage(*!*from, text*/!*) { // параметры from, text +function showMessage(*!*from, text*/!*) { // arguments: from, text - from = "** " + from + " **"; // здесь может быть сложный код оформления + from = "**" + from + "**"; alert(from + ': ' + text); } *!* -showMessage('Маша', 'Привет!'); -showMessage('Маша', 'Как дела?'); +showMessage('Ann', 'Hello!'); // **Ann**: Hello! +showMessage('Ann', "What's up?"); // **Ann**: What's up? */!* ``` -**Параметры копируются в локальные переменные функции**. +In the example above, the function has two parameters: `from` and `text`. -Например, в коде ниже есть внешняя переменная `from`, значение которой при запуске функции копируется в параметр функции с тем же именем. Далее функция работает уже с параметром: +When the function is called, the values in the brackets are copied to local variables `from` and `next`. + +Note that the function can modify those local variables freely, they are not seen from outside anyway: ```js //+ run function showMessage(from, text) { *!* - from = '**' + from + '**'; // меняем локальную переменную from + from = '**' + from + '**'; // changes the local from */!* alert( from + ': ' + text ); } -let from = "Маша"; +let from = "Ann"; -showMessage(from, "Привет"); +showMessage(from, "Hello"); -alert( from ); // старое значение from без изменений, в функции была изменена копия +// the old value of "from" is still here, the function modified a local copy +alert( from ); // Ann ``` -## Аргументы по умолчанию +## Default arguments -Функцию можно вызвать с любым количеством аргументов. +A function can be *called* with any number of arguments. If a parameter is not provided, but listed in the declaration, then its value becomes `undefined`. -Если параметр не передан при вызове -- он считается равным `undefined`. - -Например, функцию показа сообщения `showMessage(from, text)` можно вызвать с одним аргументом: +For instance, a function `showMessage(from, text)` can actually be called with a single argument: ```js -showMessage("Маша"); +showMessage("Ann"); ``` -При этом можно проверить, и если параметр не передан -- присвоить ему значение "по умолчанию": +Normally, such call would output `**Ann**: undefined`, because `text === undefined`. + +But we can modify the function to detect missed parameter and assign a "default value" to it: ```js //+ run function showMessage(from, text) { *!* if (text === undefined) { - text = 'текст не передан'; + text = 'no text given'; } */!* alert( from + ": " + text ); } -showMessage("Маша", "Привет!"); // Маша: Привет! +showMessage("Ann", "Hello!"); // Ann: Hello! *!* -showMessage("Маша"); // Маша: текст не передан +showMessage("Ann"); // Ann: no text given */!* ``` -**При объявлении функции необязательные аргументы, как правило, располагают в конце списка.** +Optional arguments are usually given at the end of the list. -Для указания значения "по умолчанию", то есть, такого, которое используется, если аргумент не указан, используется два способа: +There are three most used ways to assign default values:
b2 - 4ac
:
+For instance, let's make a maths function `calcD` to calculate a [discriminant of a quadratic polynomial] using the formula b2 - 4ac
:
```js
//+ run no-beautify
function calcD(a, b, c) {
- *!*return*/!* b*b - 4*a*c;
+ *!*return*/!* b*b - 4*a*c;
}
+// discriminant for: -4x^2 + 2x + 1
let test = calcD(-4, 2, 1);
alert(test); // 20
```
-**Для возврата значения используется директива `return`.**
+The directive `return` can be in any place of the function. When the execution reaches it, the function stops, and the value is returned to the calling code (assigned to `test` above).
-Она может находиться в любом месте функции. Как только до неё доходит управление -- функция завершается и значение передается обратно.
-
-Вызовов `return` может быть и несколько, например:
+There may be many returns, for instance:
```js
//+ run
@@ -281,40 +296,41 @@ function checkAge(age) {
if (age > 18) {
return true;
} else {
- return confirm('Родители разрешили?');
+ return confirm('Got a permission from the parents?');
}
}
-let age = prompt('Ваш возраст?');
+let age = prompt('How old are you?', 18);
-if (checkAge(age)) {
- alert( 'Доступ разрешен' );
+if ( checkAge(age) ) {
+ alert( 'Access granted' );
} else {
- alert( 'В доступе отказано' );
+ alert( 'Access denied' );
}
```
-Директива `return` может также использоваться без значения, чтобы прекратить выполнение и выйти из функции.
+The `return` can be used without a value, to exit from the function immediately.
-Например:
+For example:
```js
function showMovie(age) {
- if (!checkAge(age)) {
+ if ( !checkAge(age) ) {
*!*
return;
*/!*
}
- alert( "Фильм не для всех" ); // (*)
+ alert( "Showing you the movie" ); // (*)
// ...
}
```
-В коде выше, если сработал `if`, то строка `(*)` и весь код под ней никогда не выполнится, так как `return` завершает выполнение функции.
+In the code above, if `checkAge(age)` returns `false`, then `showMovie` won't proceed to the `alert`.
-[smart header="Значение функции без `return` и с пустым `return`"]
-В случае, когда функция не вернула значение или `return` был без аргументов, считается что она вернула `undefined`:
+
+[smart header="A result with an empty or absent `return` returns `undefined`"]
+If a function does not return a value, it is considered to return `undefined`:
```js
//+ run
@@ -323,9 +339,7 @@ function doNothing() { /* пусто */ }
alert( doNothing() ); // undefined
```
-Обратите внимание, никакой ошибки нет. Просто возвращается `undefined`.
-
-Ещё пример, на этот раз с `return` без аргумента:
+The same happens when the `return` has no argument:
```js
//+ run
@@ -338,84 +352,93 @@ alert( doNothing() === undefined ); // true
[/smart]
-## Выбор имени функции [#function-naming]
+## Naming a function [#function-naming]
-Имя функции следует тем же правилам, что и имя переменной. Основное отличие -- оно должно быть глаголом, т.к. функция -- это действие.
+Functions are actions. So their name is usually a verb.
-Как правило, используются глагольные префиксы, обозначающие общий характер действия, после которых следует уточнение.
+Usually, function names have verbal prefixes which vaguely describe the action.
-Функции, которые начинаются с `"show"` -- что-то показывают:
+Functions that shart with `"show"` -- usually show something:
```js
//+ no-beautify
-showMessage(..) // префикс show, "показать" сообщение
+showMessage(..) // shows a message
```
-Функции, начинающиеся с `"get"` -- получают, и т.п.:
+