偽數(shù)組對象(Array-like):擁有一個 length 屬性和若干索引屬性的任意對象贼陶。
工作中碰到過幾次需要將類數(shù)組對象轉(zhuǎn)化為數(shù)組處理的情況胸竞,面試時也很可能被問到着撩,因為這一個題目同時考察了以下幾點:
- 數(shù)組的方法和原型鏈:Array.prototype上的slice交掏、splice和concat方法朦拖;
- this指向綁定:call和apply;
- es6掌握情況:Array.from();
下面我們就來總結(jié)一下類數(shù)組對象(Array-like)轉(zhuǎn)化為數(shù)組(Array)的幾種方法:
1.slice
基礎(chǔ)語法:
slice() 方法返回一個新的數(shù)組對象驻襟,這一對象是一個由 begin 和 end 決定的原數(shù)組的淺拷貝(包括 begin夺艰,不包括end)。原始數(shù)組不會被改變沉衣。
var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]
轉(zhuǎn)化類數(shù)組
slice
方法可以用來將一個類數(shù)組(Array-like)對象/集合轉(zhuǎn)換成一個新數(shù)組郁副。你只需將該方法綁定到這個對象上。 一個函數(shù)中的 arguments
就是一個類數(shù)組對象的例子豌习。
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3);
結(jié)果: [1, 2, 3]
Array.prototype.slice.call({0:0,1:1,2:2,3:3,4:4,length:5})
結(jié)果:[0, 1, 2, 3,4]
Array.prototype.slice.call({0:0,1:1,2:2,3:3,4:4,length:5},1,3)
結(jié)果:[1, 2]
你也可以簡單的使用 [].slice.call(arguments) 來代替
2.splice
基礎(chǔ)語法:
splice() 方法通過刪除或替換現(xiàn)有元素或者原地添加新的元素來修改數(shù)組,并以數(shù)組形式返回被修改的內(nèi)容存谎。此方法會改變原數(shù)組。
var months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb');
// inserts at index 1
console.log(months);
// expected output: Array ['Jan', 'Feb', 'March', 'April', 'June']
months.splice(4, 1, 'May');
// replaces 1 element at index 4
console.log(months);
// expected output: Array ['Jan', 'Feb', 'March', 'April', 'May']
轉(zhuǎn)化類數(shù)組
和slice相似肥隆,不同的是會改變原對象既荚,并且第一個參數(shù)(開始位置)必須傳:
Array.prototype.splice.call({0:0,1:1,length:2},0);
結(jié)果:[0,1]
Array.prototype.splice.call({0:0,1:1,2:2,3:3,4:4,length:5},1,3)
結(jié)果:[1, 2, 3]
concat
基礎(chǔ)語法:
concat() 方法用于合并兩個或多個數(shù)組。此方法不會更改現(xiàn)有數(shù)組栋艳,而是返回一個新數(shù)組恰聘。
['a', 'b', 'c'].concat(['d', 'e', 'f']);
// expected output: Array ["a", "b", "c", "d", "e", "f"]
[1, 2, 3].concat( [4, 5, 6], [7, 8, 9]);
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]
['a', 'b', 'c'].concat(1, [2, 3]);
// results in ['a', 'b', 'c', 1, 2, 3]
轉(zhuǎn)化類數(shù)組
這里利用apply可以把類數(shù)組對象分解成多個參數(shù)傳入concat方法:
Array.concat.apply([], {0:0,1:1,2:2,length:3});
結(jié)果:[0, 1, 2]
等價于:
[].concat(0,1,2)
4.Es6 Array.from
Array.from()
方法從一個類似數(shù)組或可迭代對象中創(chuàng)建一個新的,淺拷貝的數(shù)組實例吸占。 可以通過以下方式來創(chuàng)建數(shù)組對象:
- 偽數(shù)組對象(擁有一個
length
屬性和若干索引屬性的任意對象) - 可迭代對象(可以獲取對象中的元素,如 Map和 Set 等)
Array.from('foo');
轉(zhuǎn)化數(shù)組:["f", "o", "o"]
let s = new Set(['foo', window]);
Array.from(s);
轉(zhuǎn)化set:["foo", window]
let m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m);
轉(zhuǎn)化map:[[1, 2], [2, 4], [4, 8]]
function f() {
return Array.from(arguments);
}
f(1, 2, 3);
轉(zhuǎn)化Array-like: [1, 2, 3]
Array.from的方便之處是它的第二個參數(shù)可以設(shè)置一個函數(shù)憨琳,新數(shù)組中的每個元素會執(zhí)行該函數(shù):
Array.from([1, 2, 3], x => x + x);
結(jié)果:[2, 4, 6]
Array.from({length: 5}, (v, i) => i);
結(jié)果: [0, 1, 2, 3, 4]
示例:合并數(shù)組并去重
利用set中元素的唯一性,和Array.from可以把set轉(zhuǎn)化為array的能力旬昭,我們可以封裝一個數(shù)組去重的函數(shù):
function combine(){
//Array-like to Array
let arr = [].concat.apply([], arguments);
return Array.from(new Set(arr));
}
var m = [1, 2, 2], n = [2,3,3], k = [1, 2, 6];
combine(m,n)
結(jié)果:[1, 2, 3]
combine(m,n,k)
結(jié)果:[1, 2, 3, 6]
寫在最后
注意以上方式都是淺拷貝篙螟,處理引用類型時需要多加小心。