...args剩余參數(shù)(展開運(yùn)算符)
允許一個(gè)表達(dá)式在某處展開。展開運(yùn)算符在多個(gè)參數(shù)(用于函數(shù)調(diào)用)或多個(gè)元素(用于數(shù)組字面量)或者多個(gè)變量(用于解構(gòu)賦值)的地方可以使用暇榴。剩余參數(shù)語法允許我們將一個(gè)不定數(shù)量的參數(shù)表示為一個(gè)數(shù)組厚棵。
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
console.log(sum(1, 2, 3));
// expected output: 6
console.log(sum(1, 2, 3, 4));
// expected output: 10
描述
如果函數(shù)的最后一個(gè)命名參數(shù)以...為前綴,則它將成為一個(gè)數(shù)組蔼紧,其中從0(包括)到theArgs.length(排除)的元素由傳遞給函數(shù)的實(shí)際參數(shù)提供婆硬。
用法
function(a, b, ...theArgs) {
// ...
}
在上面的例子中,theArgs將收集該函數(shù)的第三個(gè)參數(shù)(因?yàn)榈谝粋€(gè)參數(shù)被映射到a奸例,而第二個(gè)參數(shù)映射到b)和所有后續(xù)參數(shù)彬犯。
函數(shù)調(diào)用中使用展開運(yùn)算符
在以前我們會(huì)使用apply方法來將一個(gè)數(shù)組展開成多個(gè)參數(shù):
function test(a, b, c) { }
var args = [0, 1, 2];
test.apply(null, args);
如上,我們把a(bǔ)rgs數(shù)組當(dāng)作實(shí)參傳遞給了a,b,c查吊,這邊正是利用了Function.prototype.apply的特性谐区。
不過有了ES6,我們就可以更加簡(jiǎn)潔地來傳遞數(shù)組參數(shù):
function test(a,b,c) { }
var args = [0,1,2];
test(...args);
我們使用...展開運(yùn)算符就可以把a(bǔ)rgs直接傳遞給test()函數(shù)逻卖。
數(shù)組字面量中使用展開運(yùn)算符
在ES6的世界中宋列,我們可以直接加一個(gè)數(shù)組直接合并到另外一個(gè)數(shù)組當(dāng)中:
var arr1=['a','b','c'];
var arr2=[...arr1,'d','e']; //['a','b','c','d','e']
展開運(yùn)算符也可以用在push函數(shù)中,可以不用再用apply()函數(shù)來合并兩個(gè)數(shù)組:
var arr1=['a','b','c'];
var arr2=['d','e'];
arr1.push(...arr2); //['a','b','c','d','e']
用于解構(gòu)賦值
解構(gòu)賦值也是ES6中的一個(gè)特性评也,而這個(gè)展開運(yùn)算符可以用于部分情景:
let [arg1,arg2,...arg3] = [1, 2, 3, 4];
arg1 //1
arg2 //2
arg3 //['3','4']
展開運(yùn)算符在解構(gòu)賦值中的作用跟之前的作用看上去是相反的炼杖,將多個(gè)數(shù)組項(xiàng)組合成了一個(gè)新數(shù)組灭返。
不過要注意,解構(gòu)賦值中展開運(yùn)算符只能用在最后:
let [arg1,...arg2,arg3] = [1, 2, 3, 4]; //報(bào)錯(cuò)
類數(shù)組對(duì)象變成數(shù)組
展開運(yùn)算符可以將一個(gè)類數(shù)組對(duì)象變成一個(gè)真正的數(shù)組對(duì)象:
let a=new Set([1,2,3,4,5,2,1]) // a : Set(5) {1, 2, 3, 4, 5}
let b=[...a] // (5) [1, 2, 3, 4, 5]
ES7草案中的對(duì)象展開運(yùn)算符
ES7中的對(duì)象展開運(yùn)算符符可以讓我們更快捷地操作對(duì)象:
let {x,y,...z}={x:1,y:2,a:3,b:4};
x; //1
y; //2
z; //{a:3,b:4}
如上坤邪,我們可以將一個(gè)對(duì)象當(dāng)中的對(duì)象的一部分取出來成為一個(gè)新對(duì)象賦值給展開運(yùn)算符的參數(shù)熙含。
同時(shí),我們也可以像數(shù)組插入那樣將一個(gè)對(duì)象插入另外一個(gè)對(duì)象當(dāng)中:
let z={a:3,b:4};
let n={x:1,y:2,...z};
n; //{x:1,y:2,a:3,b:4}
另外還要很多用處罩扇,比如可以合并兩個(gè)對(duì)象:
let a={x:1,y:2};
let b={z:3};
let ab={...a,...b};
ab //{x:1,y:2,z:3}
arguments 對(duì)象
在函數(shù)代碼中婆芦,使用特殊對(duì)象 arguments,開發(fā)者無需明確指出參數(shù)名喂饥,就能訪問它們。
例如肠鲫,在函數(shù) sayHi() 中,第一個(gè)參數(shù)是 message。用 arguments[0] 也可以訪問這個(gè)值躬窜,即第一個(gè)參數(shù)的值(第一個(gè)參數(shù)位于位置 0谬盐,第二個(gè)參數(shù)位于位置 1,依此類推)渣锦。
因此硝岗,無需明確命名參數(shù),就可以重寫函數(shù):
function sayHi(message) {
alert(arguments[0]); // 此處將打印message參數(shù)的值
}
檢測(cè)參數(shù)個(gè)數(shù)
還可以用 arguments 對(duì)象檢測(cè)函數(shù)的參數(shù)個(gè)數(shù)袋毙,引用屬性 arguments.length 即可型檀。
下面的代碼將輸出每次調(diào)用函數(shù)使用的參數(shù)個(gè)數(shù):
function howManyArgs() {
alert(arguments.length);
}
howManyArgs("string", 45);
howManyArgs();
howManyArgs(12); // 上面這段代碼將依次顯示 "2"、"0" 和 "1"听盖。
模擬函數(shù)重載
用 arguments 對(duì)象判斷傳遞給函數(shù)的參數(shù)個(gè)數(shù)胀溺,即可模擬函數(shù)重載:
function doAdd() {
if(arguments.length == 1) {
alert(arguments[0] + 5);
} else if(arguments.length == 2) {
alert(arguments[0] + arguments[1]);
}
}
doAdd(10); //輸出 "15"
doAdd(40, 20); //輸出 "60"
當(dāng)只有一個(gè)參數(shù)時(shí),doAdd() 函數(shù)給參數(shù)加 5皆看。如果有兩個(gè)參數(shù)仓坞,則會(huì)把兩個(gè)參數(shù)相加,返回它們的和腰吟。所以无埃,doAdd(10) 輸出的是 "15",而 doAdd(40, 20) 輸出的是 "60"毛雇。
...args剩余參數(shù)和 arguments對(duì)象的區(qū)別
剩余參數(shù)和 arguments對(duì)象之間的區(qū)別主要有三個(gè):
1.剩余參數(shù)只包含那些沒有對(duì)應(yīng)形參的實(shí)參嫉称,而 arguments 對(duì)象包含了傳給函數(shù)的所有實(shí)參。
2.arguments對(duì)象不是一個(gè)真正的數(shù)組禾乘,而剩余參數(shù)是真正的 Array實(shí)例澎埠,也就是說你能夠在它上面直接使用所有的數(shù)組方法,比如 sort始藕,map蒲稳,forEach或pop氮趋。
3.arguments對(duì)象還有一些附加的屬性 (如callee屬性)。
更多參考
[MDN 展開語法
](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
[MDN Arguments 對(duì)象
](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments)