1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
---
title: Остаточные параметры (rest parameters)
slug: Web/JavaScript/Reference/Functions/Rest_parameters
tags:
- JavaScript
- Остаточные параметры
- Функции
translation_of: Web/JavaScript/Reference/Functions/rest_parameters
---
<div>{{jsSidebar("Functions")}} </div>
<p>Синтаксис <strong>остаточных параметров</strong> функции позволяет представлять неограниченное множество аргументов в виде массива.</p>
<p>{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}</p>
<h2 id="Syntax">Синтаксис</h2>
<pre class="brush: js">function(a, b, ...theArgs) {
// ...
}
</pre>
<h2 id="Описание">Описание</h2>
<p>Если последний именованный аргумент функции имеет префикс <code>...</code>, он автоматически становится массивом с элементами от <code>0</code> до <code>theArgs.length-1</code> в соответствии с актуальным количеством аргументов, переданных в функцию.</p>
<pre class="brush: js">function myFun(a, b, ...manyMoreArgs) {
console.log("a", a);
console.log("b", b);
console.log("manyMoreArgs", manyMoreArgs);
}
myFun("один", "два", "три", "четыре", "пять", "шесть");
// Console Output:
// a, один
// b, два
// manyMoreArgs, [три, четыре, пять, шесть]
</pre>
<h3 id="Отличия_остаточных_параметров_от_объекта_arguments">Отличия остаточных параметров от объекта <code>arguments</code></h3>
<p>Существует три основных отличия остаточных параметров от объекта <a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments" title="arguments"><code>arguments</code></a>:</p>
<ul>
<li>остаточные параметры включают только те, которым не задано отдельное имя, в то время как объект <code>arguments</code> содержит все аргументы, передаваемые в функцию;</li>
<li>объект <code>arguments</code> не является массивом, в то время как остаточные параметры являются экземпляром <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array" title="Array"><code>Array</code></a> и методы <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/sort" title="Array sort method"><code>sort</code></a>, <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/map" title="Array map method"><code>map</code></a>, <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach" title="Array forEach method"><code>forEach</code></a> или <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/pop" title="Array pop method"><code>pop</code></a> могут непосредственно у них использоваться;</li>
<li>объект <code>arguments</code> имеет дополнительную функциональность, специфичную только для него (например, свойство <code>callee</code>).</li>
</ul>
<h3 id="Из_аргументов_в_массив">Из аргументов в массив</h3>
<p>Остаточные параметры были введены для уменьшения количества шаблонного кода:</p>
<pre class="brush: js">// До появления остаточных параметров "arguments" конвертировали в обычный массив используя:
function f(a, b) {
var normalArray = Array.prototype.slice.call(arguments);
// -- или --
var normalArray = [].slice.call(arguments);
// -- или --
var normalArray = Array.from(arguments);
var first = normalArray.shift(); // OK, даёт первый аргумент
var first = arguments.shift(); // ERROR (arguments не является обычным массивом)
}
// Теперь мы можем легко получить остаточные параметры как обычный массив
function f(...args) {
var normalArray = args;
var first = normalArray.shift(); // OK, даёт первый аргумент
}</pre>
<h3 id="Деструктуризация_остаточных_параметров">Деструктуризация остаточных параметров</h3>
<p>Остаточные параметры могут быть деструктурированы (только массивы). Это означает, что их данные могут быть заданы как отдельные значения. Смотрите <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Деструктурирующее присваивание</a>.</p>
<pre><code>function f(...[a, b, c]) {
return a + b + c;
}
f(1) // NaN (b и c равны undefined)
f(1, 2, 3) // 6
f(1, 2, 3, 4) // 6 (четвёртый параметр не деструктурирован)</code></pre>
<h2 id="Example">Примеры</h2>
<p>В этом примере первый аргумент задан как <code>"a"</code>, второй как <code>"b"</code>, так что эти аргументы используются как обычно. Однако третий аргумент <code>"manyMoreArgs"</code> будет массивом, который содержит 3-й, 4-й, 5-й, 6-й ... n-й аргументы, которые передаст пользователь.</p>
<pre class="brush: js">function myFun(a, b, ...manyMoreArgs) {
console.log("a", a);
console.log("b", b);
console.log("manyMoreArgs", manyMoreArgs);
}
myFun("один", "два", "три", "четыре", "пять", "шесть");
// a, один
// b, два
// manyMoreArgs, [три, четыре, пять, шесть]</pre>
<p>Ниже... даже если передано одно значение последним аргументом, оно всё равно помещается в массив.</p>
<pre class="brush: js">// использование той же функции, что и в примере выше
myFun("один", "два", "три");
// a, один
// b, два
// manyMoreArgs, [три]</pre>
<p>Ниже... третий аргумент не был передан, но "manyMoreArgs" всё ещё массив (хотя и пустой).</p>
<pre class="brush: js">// использование той же функции, что и в примере выше
myFun("один", "два");
// a, один
// b, два
// manyMoreArgs, []</pre>
<p>Поскольку <code>theArgs</code> является массивом, количество элементов в нём определяется свойством <code>length</code>:</p>
<pre class="brush: js">function fun1(...theArgs) {
console.log(theArgs.length);
}
fun1(); // 0
fun1(5); // 1
fun1(5, 6, 7); // 3</pre>
<p>В следующем примере, остаточные параметры используются для сбора всех аргументов после первого в массив. Каждый из них умножается на первый параметр и возвращается массив:</p>
<pre class="brush: js"><code>function multiply(multiplier, ...theArgs) {
return theArgs.map(function(element) {
return multiplier * element;
});
}
var arr = multiply(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]</code></pre>
<p>Методы <code>Array</code> могут быть использованы на остаточных параметрах, но не на объекте <code>arguments</code>: </p>
<pre class="brush: js">function sortRestArgs(...theArgs) {
var sortedArgs = theArgs.sort();
return sortedArgs;
}
console.log(sortRestArgs(5, 3, 7, 1)); // 1, 3, 5, 7
function sortArguments() {
var sortedArgs = arguments.sort();
return sortedArgs; // это никогда не выполнится
}
console.log(sortArguments(5, 3, 7, 1)); // TypeError (arguments.sort is not a function)</pre>
<p>Чтобы использовать методы <code>Array</code> на объекте <code>arguments</code>, нужно преобразовать его в настоящий массив.</p>
<pre class="brush: js"><code>function sortArguments() {
var args = Array.from(arguments);
var sortedArgs = args.sort();
return sortedArgs;
}
console.log(sortArguments(5, 3, 7, 1)); // 1, 3, 5, 7</code></pre>
<h2 id="Спецификации">Спецификации</h2>
{{Specifications}}
<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2>
<div>{{Compat}}</div>
<div id="compat-mobile"></div>
<h2 id="See_also">Смотрите также</h2>
<ul>
<li><a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments" title="arguments">Объект arguments</a></li>
<li><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array" title="Array">Array</a></li>
<li><a href="/ru/docs/Web/JavaScript/Reference/Functions" title="Functions and function scope">Функции</a></li>
<li><a href="/ru/docs/Web/JavaScript/Reference/Operators/Spread_operator" title="spread operator">Оператор распространения</a></li>
<li><a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters">Оригинальное предложение на ecmascript.org</a></li>
<li><a class="external" href="http://javascriptweblog.wordpress.com/2011/01/18/javascripts-arguments-object-and-beyond/">JavaScript arguments object and beyond</a></li>
</ul>
|