diff options
Diffstat (limited to 'files/ru/web/javascript/reference/functions/default_parameters')
-rw-r--r-- | files/ru/web/javascript/reference/functions/default_parameters/index.html | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/functions/default_parameters/index.html b/files/ru/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..2e6568b816 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,217 @@ +--- +title: Параметры по умолчанию +slug: Web/JavaScript/Reference/Functions/Default_parameters +tags: + - ECMAScript6 + - JavaScript + - Функции + - Экспериментальный +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +<div>{{jsSidebar("Functions")}}</div> + +<p><strong>Параметры по умолчанию</strong> позволяют задавать формальным параметрам функции значения по умолчанию в случае, если функция вызвана без аргументов, или если параметру явным образом передано значение <code>undefined</code>.</p> + +<p>{{EmbedInteractiveExample("pages/js/functions-default.html")}}</p> + +<h2 id="Syntax" name="Syntax">Синтаксис</h2> + +<pre class="syntaxbox">function [<em>name</em>]([<em>param1</em>[ = defaultValue1 ][, ..., <em>paramN</em>[ = defaultValueN ]]]) { + <em>statements</em> +} +</pre> + +<h2 id="Example" name="Example">Описание</h2> + +<p>В JavaScript параметры функции, которым при ее вызове не передаются значения, принимают по умолчанию значение <code>{{jsxref("undefined")}}</code>. Однако в некоторых случаях может быть полезно задать иное значение по умолчанию. Именно для таких случаев предназначены параметры по умолчанию.</p> + +<p>В прошлом для проверки параметров и задания их значений по умолчанию использовался код в теле функции, в котором проверялось, не равны ли значения параметров <code>undefined</code>.</p> + +<p>В приведённом ниже примере, в случае если при вызове функции значение для параметра <code>b</code> не передавалось, его значением становилось <code>undefined</code>, и результатом вычисления <code>a * b</code> в функции <code>multiply</code> получалось значение <code>NaN</code>.</p> + +<pre class="brush: js">function multiply(a, b) { + return a * b; +} + +multiply(5, 2); // 10 +multiply(5); // NaN !</pre> + +<p>Чтобы такого не происходило, в теле функции использовался код подобный тому, что находится во второй строчке, где в случае, если функция <code>multiply</code> вызывалась только c одним аргументом, параметру <code>b</code> присваивалось значение <code>1</code>:</p> + +<pre class="brush: js">function multiply(a, b) { + b = typeof b !== 'undefined' ? b : 1; + return a*b; +} + +multiply(5, 2); // 10 +multiply(5); // 5 +</pre> + +<p>С появлением в ES2015 параметров по умолчанию стало возможным обходиться без проверки параметров в теле функции. Так, в приведенном выше примере достаточно в заголовке функции указать <code>1</code> в качестве значения по умолчанию для параметра <code>b</code>:</p> + +<pre class="brush: js">function multiply(a, b = 1) { + return a*b; +} + +multiply(5, 2); // 10 +multiply(5); // 5 +multiply(5, undefined); // 5</pre> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Передача_значения_undefined_в_сравнении_с_передачей_других_ложных_значений">Передача значения <code>undefined</code> в сравнении с передачей других "ложных" значений</h3> + +<p>Значение по умолчанию присваивается формальному параметру только если при вызове функции значение для данного параметра не было передано или было явным образом передано <code>undefined</code>. Если формальному параметру при вызове передано любое значение, отличное от <code>undefined</code>, в том числе одно из <a href="/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/Falsy">"ложных"</a> значений, таких как <code>false</code>, <code>0</code>, <code>""</code>, <code>''</code>, <code>``</code>, <code>null</code>, <code>NaN</code>, то в этом случае значение по умолчанию присвоено параметру не будет. Это иллюстрирует следующий пример:</p> + +<pre class="brush: js">function test(num = 1) { + console.log(typeof num); +} + +// num не прередано, или передано undefined: +test(); // 'number' (num получил значение 1) +test(undefined); // 'number' (и здесь num получил значение 1) + +// num передано значение null или другое "ложное" значение: +test(''); // 'string' (num получил значение '') +test(null); // 'object' (num получил значение null) +</pre> + +<h3 id="Параметры_по_умолчанию_вычисляются_в_момент_вызова_функции">Параметры по умолчанию вычисляются в момент вызова функции</h3> + +<p>В Javascript параметры по умолчанию вычисляются в момент вызова функции. В отличие от языка Python, при каждом вызове функции создается новое лексическое окружение функции.</p> + +<pre class="brush: js">function append(value, array = []) { + array.push(value); + return array; +} + +append(1); // [1] +append(2); // [2], а не [1, 2] + +</pre> + +<p>Это верно и для функций, и для переменных:</p> + +<pre class="brush: js">function callSomething(thing = something()) { + return thing; +} + +let numberOfTimesCalled = 0; +function something() { + numberOfTimesCalled += 1; + return numberOfTimesCalled; +} + +callSomething(); // 1 +callSomething(); // 2 +</pre> + +<h3 id="Параметры_по_умолчанию_доступны_в_следующих_параметрах_по_умолчанию">Параметры по умолчанию доступны в следующих параметрах по умолчанию</h3> + +<p>В параметрах по умолчанию можно использовать значения предыдущих (расположеннных левее в списке) параметров:</p> + +<pre class="brush: js">function greet(name, greeting, message = greeting + ' ' + name) { + return [name, greeting, message]; +} + +greet('David', 'Hi'); // ["David", "Hi", "Hi David"] +greet('David', 'Hi', 'Happy Birthday!'); // ["David", "Hi", "Happy Birthday!"]</pre> + +<p>Следующий пример пример еще раз иллюстирует эту возможность, а также позволяет еще раз сравнить два способа достижения одного и того же результата: с использованием инициализации параметров по умолчанию и без ее использования:</p> + +<pre class="brush: js">function go() { + return ":P" +} + +function withDefaults(a, b = 5, c = b, d = go(), e = this, + f = arguments, g = this.value) { + return [a,b,c,d,e,f,g]; +} +function withoutDefaults(a, b, c, d, e, f, g){ + switch(arguments.length){ + case 0: + a + case 1: + b = 5 + case 2: + c = b + case 3: + d = go(); + case 4: + e = this + case 5: + f = arguments + case 6: + g = this.value; + default: + } + return [a,b,c,d,e,f,g]; +} + +withDefaults.call({value:"=^_^="}); +// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] + + +withoutDefaults.call({value:"=^_^="}); +// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] +</pre> + +<h3 id="Инициализация_с_помощью_функций_определяемых_в_теле_функции">Инициализация с помощью функций, определяемых в теле функции</h3> + +<p>Начиная с версии Gecko 33 {{geckoRelease(33)}} функции, определяемые в теле самой функции, не могут быть использованы для инициализации параметров по умолчанию; попытка это сделать приведет к ошибке {{jsxref("ReferenceError")}}. Параметры по умолчанию всегда вычисляются до обработки описаний функций, определяемых в теле функции.</p> + +<pre class="brush: js">// Вызовет ошибку ReferenceError! +function f(a = go()) { + function go(){return ":P"} +} +f(); // ReferenceError: go is not defined +</pre> + +<h3 id="Параметры_без_инициализации_следующие_после_инициализируемых_параметров">Параметры без инициализации, следующие после инициализируемых параметров</h3> + +<p>До появления версии Gecko 26 {{geckoRelease(26)}}, следующий код приводил к {{jsxref("SyntaxError")}}. Это было исправлено в {{bug(777060)}} и с тех пор работает корректно. Аргументы, передаваемые при вызове функции, становятся значениями формальных параметров независимо от наличия у последних инициализации по умолчанию, а также независимо от присутствия у функции других параметров, находящихся правее в списке параметров и не имеющих инициализации.</p> + +<pre class="brush: js">function f(x=1, y) { + return [x, y]; +} + +f(); // [1, undefined]; +f(2); // [2, undefined]; +</pre> + +<h3 id="Инициализация_по_умолчанию_деструктурированных_параметров">Инициализация по умолчанию деструктурированных параметров</h3> + +<p>При инициализации параметров по умолчанию можно использовать синтаксическую конструкцию деструктурирующего присваивания:</p> + +<pre class="brush: js">function f([x, y] = [1, 2], {z: z} = {z: 3}) { + return x + y + z; +} + +f(); // 6</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Спецификация</th> + <th scope="col">Статус</th> + <th scope="col">Комментарий</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-function-definitions', 'Определение функций')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Изначальное определение.</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>{{Compat("javascript.functions.default_parameters")}}</p> + +<h2 id="See_also" name="See_also">Смотрите также</h2> + +<ul> + <li><a href="http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values" rel="external">Оригинальное предложение на ecmascript.org</a></li> +</ul> |