数组
在js中,数组可以容纳任何类型的值,可以是字符串、数字、对象,甚至是其他数组(多维数组就是通过这种方式来实现的):
var a = [1, '2', [3]];
a.length; // 3
对数组声明后即可向其中加入值,不需要预先设定大小:
var a = [];
a.length; // 0
a[0] = 1;
a[1] = '2';
a[2] = [3];
a.length; // 3
使用delete运算符可以将单元从数组中删除,但是删除后,数组的length属性并不会发生变化。
创建稀疏数组,空白单元为undefined,但仍占有length;字符串键值不占有length;字符串键值能够被强制转换为十进制数字的话,会被当作数字索引来处理:
var a = [];
a[0] = 1;
a['2'] = 2; // 稀疏数组,仍存在a[1];该字符串键值可以转换为数字,当作a[2]处理
a['foo'] = 3; // 该字符串键值不能转为数字,不占有length
a.length; // 3
a[0] === 1
a[1] === undefined
a[2] === 2
类数组
有时需要将类数组(一组通过数字索引的值)转换为真正的数组,这一般通过数组工具函数(如indexof(..)、concat(..)、forEach(..)等)实现。
一些DOM查询操作会返回DOM元素列表,它们并非真正意义上的数组,但十分类似;通过arguments对象(类数组)将函数的参数当作列表来访问(从ES6开始已废止)。工具函数slice(..)经常被用于这类转换:
function foo() {
var arr = Array.prototype.slice.call(arguments);
arr.push('bam');
console.log(arr);
}
foo('bar', 'baz'); // ['bar', 'baz', 'bam']
ES6中的内置工具函数Array.from(..)也能实现同样的功能:
var arr = Array.from(arguments);
类数组详解
定义
拥有length属性,其他属性(索引)为非负整数(对象中的索引会被当做字符串来处理,这里你可以当做是个非负整数串来理解);不具有数组所具有的方法。实际上,只要有length属性,且它的属性值为number类型就行。
类数组示例:
var a = {'1':'gg','2':'love','4':'meimei',length:5};
Array.prototype.join.call(a,'+'); // '+gg+love+meimei'
非类数组示例(没有length属性,所以不是类数组):
var c = {'1':2};
js中常见的类数组有arguments对象和DOM方法的返回结果。
类数组判断
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
}
类数组表现
之所以称为‘类数组’,就是因为和‘数组’类似。不能直接使用数组方法,但你可以像使用数组那样,使用类数组。
var a = {'0':'a', '1':'b', '2':'c', length:3}; // An array-like object
Array.prototype.join.call(a, '+''); // => 'a+b+c'
Array.prototype.slice.call(a, 0); // => ['a','b','c']
Array.prototype.map.call(a, function(x) {
return x.toUpperCase();
}); // => ['A','B','C']
类数组对象转化为数组
有时候处理类数组对象的最好方法是将其转化为数组,然后就可以直接使用数组方法啦。
Array.prototype.slice.call(arguments)
var a = {'0':1,'1':2,'2':3,length:3};
var arr = Array.prototype.slice.call(a); // arr === [1,2,3]