类数组是什么

简介: 类数组是什么

类似数组的对象

如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object)。

var obj = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};
 
obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function

上面代码中,对象obj就是一个类似数组的对象。但是,“类似数组的对象”并不是数组,因为它们不具备数组特有的方法。对象obj没有数组的push方法,使用该方法就会报错。


“类似数组的对象”的根本特征,就是具有length属性。只要有length属性,就可以认为这个对象类似于数组。但是有一个问题,这种length属性不是动态值,不会随着成员的变化而变化。

var obj = {
  length: 0
};
obj[3] = 'd';
obj.length // 0

上面代码为对象obj添加了一个数字键,但是length属性没变。这就说明了obj不是数组。

典型的“类似数组的对象”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串

// arguments对象
function args() { return arguments }
var arrayLike = args('a', 'b');
 
arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false
 
// DOM元素集
var elts = document.getElementsByTagName('h3');
elts.length // 3
elts instanceof Array // false
 
// 字符串
'abc'[1] // 'b'
'abc'.length // 3
'abc' instanceof Array // false

上面代码包含三个例子,它们都不是数组(instanceof运算符返回false),但是看上去都非常像数组。

数组的slice方法可以将“类似数组的对象”变成真正的数组。

var arr = Array.prototype.slice.call(arrayLike);

除了转为真正的数组,“类似数组的对象”还有一个办法可以使用数组的方法,就是通过call()把数组的方法放到对象上面。

function print(value, index) {
  console.log(index + ' : ' + value);
}
 
Array.prototype.forEach.call(arrayLike, print);

上面代码中,arrayLike代表一个类似数组的对象,本来是不可以使用数组的forEach()方法的,但是通过call(),可以把forEach()嫁接到arrayLike上面调用。

下面的例子就是通过这种方法,在arguments对象上面调用forEach方法。

// forEach 方法
function logArgs() {
  Array.prototype.forEach.call(arguments, function (elem, i) {
    console.log(i + '. ' + elem);
  });
}
 
// 等同于 for 循环
function logArgs() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(i + '. ' + arguments[i]);
  }
}


字符串也是类似数组的对象,所以也可以用Array.prototype.forEach.call遍历。

Array.prototype.forEach.call('abc', function (chr) {
  console.log(chr);
});
// a
// b
// c

注意,这种方法比直接使用数组原生的forEach要慢,所以最好还是先将“类似数组的对象”转为真正的数组,然后再直接调用数组的forEach方法。

var arr = Array.prototype.slice.call('abc');
arr.forEach(function (chr) {
  console.log(chr);
});
// a
// b
// c
目录
相关文章
|
7月前
|
前端开发 算法 JavaScript
2695. 包装数组
2695. 包装数组
38 0
|
编译器 C++ 开发者
C++构造函数在数组中的使用
C++构造函数在数组中的使用
95 0
|
7月前
|
JavaScript 前端开发 索引
往数组添加对象的方法
往数组添加对象的方法
34 0
|
7月前
|
JavaScript 前端开发 索引
数组相关方法
数组相关方法
40 0
|
存储 索引
数组和对象有什么区别?
数组和对象有什么区别?
88 0
|
前端开发
数组常用的几个方法
数组常用的几个方法
47 0
|
存储 JavaScript 前端开发
什么是数组,什么是对象,他们的区别是什么
什么是数组,什么是对象,他们的区别是什么
69 0
声明数组和初始化数组
声明数组和初始化数组。
48 0
数组的相关方法
数组的相关方法
64 0
下一篇
DataWorks