1. 什么是類數組ArrayLike
- 擁有length屬性,其它屬性(索引)為非負整數(對象中的索引會被當做字符串來處理,這里你可以當做是個非負整數串來理解)
- 不具有數組所具有的方法
//類數組示例 var a = {'1':'gg','2':'love','4':'meimei',length:5}; Array.prototype.join.call(a,'+');//'+gg+love++meimei' //非類數組示例 var c = {'1':2}; //沒有length屬性就不是類數組
javascript中常見的類數組有arguments
對象和DOM方法的返回結果。
比如 document.getElementsByTagName()
。
2. 判斷一個對象是否屬於類數組
function isArrayLike(o) { if (o && // o is not null, undefined, etc. typeof o === 'object' && // o is an object isFinite(o.length) && // o.length is a finite number o.length >= 0 && // o.length is non-negative o.length===Math.floor(o.length) && // o.length is an integer o.length < 4294967296) // o.length < 2^32 return true; // Then o is array-like else return false; // Otherwise it is not }
3. 類數組轉換成數組之后進行操作有什么優勢
由於類數組不具有數組所具有的操作數組的方法,講類數組轉換為數組之后就能調用如shift,unshift,splice,slice,concat,reverse,sort等這些強大的方法,方便快捷。
4. 類數組轉換為數組方法
Array.prototype.slice.call(arrayLike)
//將arguments轉化為數組后,截取第一個元素之后的所有元素
var args = Array.prototype.slice.call(arguments,
1
);
首先Array.prototype.slice.call(arrayLike)的結果是將arrayLike對象轉換成一個Array對象。所以其后面可以直接調用數組具有的方法,例如
Array.prototype.slice.call(arrayLike).forEach(function(element,index){ //可以隨意操作每一個element了 })
(1)Array.prototype.slice表示數組的原型中的slice方法。注意這個slice方法返回的是一個Array類型的對象。
//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)附上轉成數組的通用函數
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; }
5. 將數組轉換為參數列表(類數組)
調用apply方法的時候,第一個參數是對象(this), 第二個參數是一個數組集合, 這里就說明apply的一個巧妙用法,可以將一個數組默認的轉換為一個參數列表([param1,param2,param3] 轉換為 param1,param2,param3), 這個如果讓我們用程序來實現將數組的每一個項,來轉換為參數的列表,可能都得費一會功夫,借助apply的這點特性,所以就有了以下高效率的方法。
具體可以參考前面的文章 js函數中的apply()、call()、bind()方法 ---(apply的其他巧妙用法(一般在什么情況下可以使用apply))
參考來源
1.https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-7/array-like-objects
2.JavaScript 的怪癖 8:“類數組對象”