什么是类数组
javascript中一些看起来像却不是数组的对象,叫做类数组。也就是说,为一些常规对象增加一些属性可以使其变成类数组对象。
类数组的特征:
- 有索引(数字)属性和
length
属性的对象 - 不具有数组的方法。间接调用数组的一些方法,比如
push()
可以动态的增长length
的值。
实际上,类数组的定义只有一条,具有 length
属性。
举个例子:
var array = ['name', 'age', 'sex'];//数组
var arrayLike = {
0: 'name',
1: 'age',
2: 'sex',
length: 3
}//类数组
javascript中常见的比较典型的类数组有两个:arguments
对象和一些DOM方法的返回值(如document.getElementsByTagName()
)
类数组使用数组方法的两种方式
类数组虽然和数组类似,但是不能直接使用数组的方法,可以像使用数组一样,使用类数组。
在ECMAScript5中,所有的数组方法都是通用的 。既然类数组对象没有继承Array.prototype
,当然不能再类数组对象上直接调用数组方法。尽管如此,可以使用Function.call
方法间接调用;或者在类数组中自定义数组方法,使函数体指向Array.prototype
中对应的方法体。
- 使用
Function.call
方法间接使用数组的方法
var a = {
'0': 'a',
'1': 'b',
'2': 'c',
'3': 'd',
'length': 4
}//类数组对象
Array.prototype.join.call(a, '-') //"a-b-c-d"
Array.prototype.slice.call(a, 0) //["a", "b", "c", "d"] 真正的数组
Array.prototype.map.call(a, function(item){
return item.toUpperCase()
}) //["A", "B", "C", "D"]
Array.prototype.push.call(a, '1','23')
console.log(a) //{0: "a", 1: "b", 2: "c", 3: "d", 4: "1", 5: "1", 6: "23", length: 7}
- 在类数组对象中添加数组的方法。通过对象的属性名模拟数组的特性。
一道题目:
var obj = {
'2': 'a',
'3': 'd',
'length': 2,
'push': Array.prototype.push
}
obj.push('c');
obj.push('d');
console.log(obj)//{'2': 'c', '3': 'd', length: 2, push: f}
首先一定要明白push()
方法的实现原理。在这里,如果让类数组强行调用push
方法,则会根据length
属性值的位置进行属性的扩充。
//push()`方法的实现原理
Array.prototype.push = function () {
for(var i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return this.length;
}
//类数组使用push方法, length属性值设为3
var arrayLike = {
haha: '2rr',
hehe: 'enen',
length: 3,
push : Array.prototype.push
}
arrayLike.push(34);
console.log(arrayLike);
//改变length属性值
var arrayLike = {
haha: '2rr',
hehe: 'enen',
length: 6,
push : Array.prototype.push
}
arrayLike.push(34, 'hobby');
console.log(arrayLike);
打印结果:
将类数组转化为真正的数组
有时候处理类数组最好的办法是将其转换成真正的数组。
var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
// 1. slice
Array.prototype.slice.call(arrayLike); // ["name", "age", "sex"]
// 2. splice
Array.prototype.splice.call(arrayLike, 0); // ["name", "age", "sex"]
// 3. ES6 Array.from
Array.from(arrayLike); // ["name", "age", "sex"]
// 4. apply
Array.prototype.concat.apply([], arrayLike)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。