類數組定義
1)擁有length屬性,其它屬性(索引)為非負整數(對象中的索引會被當做字符串來處理);
2)不具有數組所具有的方法;
javascript中常見的類數組有 arguments
對象和 DOM方法的返回結果。比如 document.getElementsByTagName()
。
判斷是否是類數組
1
2
3
4
5
6
7
8
|
function
isLikeArray(o) {
if
(
typeof
o ===
'object'
&& isFinite(o.length) && o.length >= 0 && o.length < 4294967296){
// 4294967296: 2^32
return
true
}
else
{
return
false
}
}
|
類數組轉換為數組
args = Array.prototype.slice.call(arguments);
// 類數組轉換為數組首先Array.prototype.slice.call(arrayLike)的結果是將arrayLike對象轉換成一個Array對象。所以其后面可以直接調用數組具有的方法
Array.prototype.slice
slice() 方法可提取字符串的某個部分,並以新的字符串返回被提取的部分。
String 對象的方法 slice()、substring() 和 substr() (不建議使用)都可返回字符串的指定部分。slice() 比 substring() 要靈活一些,因為它允許使用負數作為參數。slice() 與 substr() 有所不同,因為它用兩個字符的位置來指定子串,而 substr() 則用字符位置和長度來指定子串。
還要注意的是,String.slice() 與 Array.slice() 相似。
Array.slice
返回值
返回一個新的數組,包含從 start 到 end (不包括該元素)的 arrayObject 中的元素。
說明
請注意,該方法並不會修改數組,而是返回一個子數組。如果想刪除數組中的一段元素,應該使用方法 Array.splice()。
(1)Array.prototype.slice表示數組的原型中的slice方法。注意這個slice方法返回的是一個Array類型的對象。
1
2
3
4
5
6
7
8
9
10
|
//slice的內部實現
Array.prototype.slice =
function
(start,end){
var
result =
new
Array();
start = start || 0;
end = end ||
this
.length;
//this指向調用的對象,當用了call后,能夠改變this的指向,也就是指向傳進來的對象,這是關鍵
for
(
var
i = start; i < end; i++){
result.push(
this
[i]);
}
return
result;
}
|
(2)能調用call的只有方法,所以不能用[].call這種形式,得用[].slice。而call的第一個參數表示真正調用slice的環境變為了arrayLike對象。所以就好像arrayLike也具有了數組的方法。
(3)附上轉成數組的通用函數
1
2
3
4
5
6
7
8
9
10
11
|
var
toArray =
function
(s){
try
{
return
Array.prototype.slice.call(s);
}
catch
(e){
var
arr = [];
for
(
var
i = 0,len = s.length; i < len; i++){
//arr.push(s[i]);
arr[i] = s[i];
//據說這樣比push快
}
return
arr;
}
|
//也可以用es6
Array.from方法轉為數組
如果有不支持Array.from方法的瀏覽器,
可以用Array.prototype.slice方法替代
const toArray = (() =>
Array.from ? Array.from : obj => [].slice.call(obj)
)();
Array.from使用
Array.from('一二三四五六七') // ["一", "二", "三", "四", "五", "六", "七"] // 等效的es5是'一二三四五六七'.split('')
Array.from(new Set([1,2,1,2])) // 等效[...new Set([1,2,1,2])] => [1,2] // 用來數組去重
Array.from(new Map([[1, 2], [2, 4], [4, 8]])) // 接受一個map
Array.from(arguments)// 接受一個類數組對象
Array.from(document.querySelectorAll('div')) Array.from({1: 2,length:3}) // [undefined, 2, undefined]
類數組和數組的區別
① instanceof
② constructor
③ toString()
④ ES 提供的方法 isArray()
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
|
<!DOCTYPE html>
<html lang=
"en"
>
<head>
<meta charset=
"UTF-8"
>
<title>Document</title>
</head>
<body>
<ul id=
"list"
>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<script type=
"text/javascript"
>
// 獲取所有li
var
lis = document.getElementsByTagName(
"li"
);
// 定義數組
var
arr = [];
// 請問有幾種方式來區別類數組和數組?
// typeof 用來判斷類型 (是值類型還是引用類型) 返回的是一個字符串
// 第一種方式 instanceof
console.log(arr
instanceof
Array);
console.log(lis
instanceof
Array);
// 第二種方式
console.log(arr.constructor === Array)
console.log(lis.constructor === Array)
// 第三種方式
console.log(Object.prototype.toString.call(arr) ===
"[object Array]"
)
console.log(Object.prototype.toString.call(lis) ===
"[object Array]"
)
// 使用ES5提供的方法
console.log(Array.isArray(arr))
console.log(Array.isArray(lis))
</script>
</body>
</html>
|
將數組轉化為類數組(參數列表)
調用apply方法的時候,第一個參數是對象(this), 第二個參數是一個數組集合, 這里就說明apply的一個巧妙用法,可以將一個數組默認的轉換為一個參數列表([param1,param2,param3] 轉換為 param1,param2,param3), 這個如果讓我們用程序來實現將數組的每一個項,來轉換為參數的列表,可能都得費一會功夫,借助apply的這點特性,所以就有了以下高效率的方法。
可以看看 js函數中的apply()、call()、bind()方法 ---(apply的其他巧妙用法(一般在什么情況下可以使用apply))
(1)Math.max 實現得到數組中最大的一項
因為Math.max 參數里面不支持Math.max([param1,param2]) 也就是數組 ,但是它支持Math.max(param1,param2,param3…),所以
可以根據剛才apply的那個特點來解決 var max=Math.max.apply(null,array),這樣輕易的可以得到一個數組中最大的一項 (apply會將一個數組裝換為一個參數接一個參數的傳遞給方法)
這塊在調用的時候第一個參數給了一個null,這個是因為沒有對象去調用這個方法,我只需要用這個方法幫我運算,得到返回的結果就行,.所以直接傳遞了一個null。
1
2
|
var
arr =
new
Array(1,2,3,4,5);
var
max = Math.max.apply(
null
,arr);
//5
|
(2)Array.prototype.push 可以實現兩個數組合並
同樣push方法沒有提供push一個數組,但是它提供了push(param1,param,…paramN);
如果我們要把 arr2展開,然后一個一個追加到arr1中去,最后讓arr1=[“1”,“2”,“3”,“4”,“5”,“6”]
arr1.push(arr2)顯然是不行的,因為這樣做會得到[“1”,“2”,“3”,[“4”,“5”,“6”]]
我們只能用一個循環去一個一個的push(當然也可以用arr1.concat(arr2),但是concat方法並不改變arr1本身,需要重新定義一個變量)
所以同樣也可以通過apply來轉換一下這個數組,即:
1
2
3
4
|
var
arr1=
new
Array(
"1"
,
"2"
,
"3"
);
var
arr2=
new
Array(
"4"
,
"5"
,
"6"
);
Array.prototype.push.apply(arr1,arr2);<br> console.log(arr1,arr2)
console.log(
"arr1="
+arr1+
",arr2="
+arr2);
|

1
|
|
也可以理解arr1調用了push方法,參數是通過apply將數組裝換為參數列表的集合.。
文章來源:https://www.cnblogs.com/jiayeyuan/p/10886568.html