数组的读和写
数组也是对象,因此通过[]访问数组元素,实际上就是通过属性名访问,[]中的会转换成字符串当做属性名来进行访问。如果[]中的是非负整数(以及和整数想相等的浮点数),则会动态改变数组元素的length属性;若不是非负整数,则会当做普通的属性名,且不会改变length值。
稀疏数组
指索引不连续的数组,其length值大于数组元素的个数。使用构造函数创建数组会生成稀疏数组:
var arr = new Array(3);
arr.length; // 3
0 in arr; // false,数组中没有元素
当在数组直接量中省略值时也会创建稀疏数组,省略的值其值为undefined,也会被当做不存在:
var arr = [,,,];
arr.length; // 3
0 in arr; // false
arr[0]; // undefined
但如果显示地设置元素值为undefined,则会被当做元素是存在的,此时不能创建稀疏数组:
var arr = [undefined,undefined,undefined];
arr.length; // 3
0 in arr; // true 数组元素存在
arr[0]; // undefined
数组元素的添加和删除
push
在数组末尾添加元素
unshift
在数组头部添加元素
delete
删除某个数组元素,但数组长度不变,数组变成了稀疏数组
pop
删除尾部元素
shift
删除头部元素
数组遍历
- for
var keys = Object.keys(arr); //获取可枚举的自有属性
var values = []; //存储属性的值
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
values[i] = arr[key];
}
上述方法考虑了数组元素索引不是整数的情况。除此外,如果需要过滤掉null、undefined、不存在的元素(用in检测),还需作进一步判断。
for in
可以处理稀疏数组,循环每次将可枚举的属性名赋值给循环变量,不存在的索引将不会遍历到。
由于该方法会枚举到继承的属性,因此如果想要自有属性,可以调用方法o.hasOwnProperty()来进行判断。
但该方法不能保证遍历顺序,因此如果依赖遍历的顺序,最好使用常规的for循环。forEach(function(x) {})
ES5提供。按索引的顺序将元素值传递给x。
ES5提供的数组方法
1. forEach
改变原来的数组,不能直接中止循环。
2. map
map方法会返回一个新数组,因此传递给map的函数应该有一个返回值。
3. filter
返回数组元素的子集。传递的函数用来进行逻辑判断,该函数返回布尔值,当返回true时的数组元素会被添加到filter返回的数组中。
4. every和some
用于逻辑判断。传入的函数需要返回布尔值。every是所有元素都返回true时,才返回true;而some是只要有元素返回true则返回true并停止循环。
5. reduce和reduceRight
传入reduce的第一个参数为进行化简操作的函数,该函数的第一个参数为到目前为止化简操作累计的结果,第二个参数为数组元素;传入reduce的第二个参数为初始值,是可选参数,即传递给函数(即第一个参数)的初始值。如果没有传第二个参数,则传入的函数的第一个参数和第二个参数依次为数组的第一、第二个元素。
reduceRight的计算方向是从数组最右边的一个元素开始。
作为数组的字符串
可用[]来访问字符串中的某个字符,比用charAt()更为简洁;同时字符串的类似于数组的事实使得通用的数组方法可以应用到字符串上:
var str = "test";
Array.prototype.join.call(str, " "); //t e s t
但需注意字符串是不可更改的,当用数组方法对字符串进行更改时会导致错误,但并没有任何提示。