1 数组简介
- 数组就是用一个变量存储一系列的值。
- js中数组项不限类型,这点与强类型语言不同。
2 创建数组
方式1
var myArray = new Array();
myArray[0] = "cyz";
myArray[1] = 18;
方式2
var myArray = new Array("cyz",18);
方式3
var myArray = ["cyz",18];
3 访问数组
- 通过索引访问数组。(从零开始)
- 数组的索引可以看作是数组的属性名(key)。
var name = myArray[0];
var age = myArray[1];
4 Array对象属性
- length:数组长度。
5 Array对象方法
1.concat():连接两个或更多的数组,并构成新的数组返回。
var resultArr = arrObj1.concat(arrObj2,arrObj3,...);
2.every():检测数组元素的每个元素是否都符合条件。(通过函数提供)
- 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
- 如果所有元素都满足条件,则返回 true。
var isAllPass = arrObj.every(function(age){
return age > 18;
})
3.filter():过滤数组,并将过滤结果构成一个新的数组。
var filterResult = arrObj.filter(function(age){
return age > 18;
})
4.indexOf():搜索数组中的元素,并返回它所在的位置。
1. 此方法内部调用的是===
,而不是==
var index = arrObj.indexOf('cyz');
5.join():把数组的所有元素放入一个字符串。
var result = arrObj.join(); //可传入分割字符,默认是','
6.lastIndexOf():返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
参考IndexOf方法
7.map():通过指定函数处理数组的每个元素,并返回处理后构成的新数组。
var result = arrObj.map(function(num){
return num * 100 + "%";
})
8.pop():删除数组的最后一个元素并返回删除的元素。
9.push():向数组的末尾添加一个或更多元素,并返回新的长度。
10.reverse():反转数组的元素顺序。
11.shift():删除并返回数组的第一个元素。
12.unshift():向数组的开头添加一个或更多元素,并返回新的长度。
13.slice():选取数组的的一部分,并返回一个新数组。
var result = arrObj.slice(startIndex(include),endIndex(uninclude));
14.some():检测数组元素中是否有元素符合指定条件。
参考every()方法。
15.sort():对数组的元素进行排序,并返回排序后的数组。
arrObj.sort(function(a, b){
return a - b;
})
16.splice():从数组中添加或删除元素。
array.splice(插入/删除元素位置,删除多少个元素,要添加的新元素1,要添加的新元素2...);
17.toString():把数组转换为字符串,并返回结果。
实际调用的是arrObj.join()方法。
18.valueOf():返回数组对象的原始值。
19.reduce():对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供。
语法:array1.reduce(callbackfn[, initialValue])
参数:
- array1:必需。一个数组对象。
- callbackfn:必须。一个接受最多四个参数的函数。对于数组中的每个元素,reduce 方法都会调用 callbackfn 函数一次。
- initialValue:可选。如果指定 initialValue,则它将用作初始值来启动累积。第一次调用 callbackfn 函数会将此值作为参数而非数组值提供。否则将以数组第一个元素提供。
返回值:通过最后一次调用回调函数获得的累积结果。
备注:
如果提供了 initialValue,则 reduce 方法会对数组中的每个元素调用一次 callbackfn 函数(按升序索引顺序)。如果未提供 initialValue,则 reduce 方法会对从第二个元素开始的每个元素调用 callbackfn 函数。
回调函数的返回值在下一次调用回调函数时作为 previousValue 参数提供。最后一次调用回调函数获得的返回值为 reduce 方法的返回值。
不为数组中缺少的元素调用该回调函数。
回调函数的语法如下所示:
function callbackfn(previousValue, currentValue, currentIndex, array1)
回调参数 | 定义 |
---|---|
previousValue | 通过上一次调用回调函数获得的值。如果向 reduce 方法提供 initialValue,则在首次调用函数时,previousValue 为 initialValue。 |
currentValue | 当前数组元素的值。 |
currentIndex | 当前数组元素的数字索引。 |
array1 | 包含该元素的数组对象。 |
若浏览器不支持,需添加如下代码:
if (!Array.prototype.reduce) {
Array.prototype.reduce = function (fun /*, initial*/ ) {
var len = this.length;
if (typeof fun != "function") throw new TypeError(); // no value to return if no initial value and an empty array
if (len == 0 && arguments.length == 1) throw new TypeError();
var i = 0;
if (arguments.length >= 2) {
var rv = arguments[1];
}
else {
do {
if (i in this) {
rv = this[i++];
break;
} // if array contains no values, no initial value to return
if (++i >= len) throw new TypeError();
} while (true);
}
for (; i < len; i++) {
if (i in this) rv = fun.call(null, rv, this[i], i, this);
}
return rv;
};
}
详情:https://msdn.microsoft.com/library/ff679975.aspx
6 清空数组
6.1 splice方法
var array = [1,2,3,...];
array.splice(0, array.length);
6.2 数组length属性
var array = [1,2,3,...];
array.length = 0;
6.3 赋值空数组
var array = [1,2,3,...];
array = [];
效率比较
var test = [];
for (var i = 0; i < 10000000; i++) {
test.push(i);
}
var start = new Date();
//test.splice(0, test.length);
//test = [];
//test.length = 0;
var end = new Date();
alert(end - start);
浏览器 | splice | length=0 | array = [] |
---|---|---|---|
chrome(56.0.2924.87) | 0 | 0 | 0 |
firefox(51.0.1) | 85 | 43 | 0 |
Edge(38.14393.0.0) | 15 | 1 | 0 |
IE(11) | 42 | 1 | 0 |
比较
1. 效率最高的是直接赋值空数组。
2. 前两种方式都可以保留数组的属性,但最后一个方法不保留。
3. 还是chrome牛b。
7 数组去重
7.1 方式一:空数组取不同
思路:创建一个结果数组,遍历原数组,若结果数组不包含原数组的项,则将该项加入结果数组中。
Array.prototype.unique = function () {
var result = [this[0]];
var i, j;
a: for (i = 1; i < this.length; i++) {
for (j = 0; j < result.length; j++) {
if (result.indexOf(this[i]) == -1) {
result.push(this[i]);
continue a;
}
}
}
return result;
}
var arrs = var arrs = ["1", NaN, "2", null, "a", "2", "b", "a", "1", undefined, 1, 2, 5, 6, 9, 7, null, 4, 5, 5, 7,undefined, NaN];
console.log(arrs.unique());
//["1", NaN, "2", null, "a", "b", undefined, 1, 2, 5, 6, 9, 7, 4, NaN]
特点:
1. 内部采用的是数组对象的indexOf()方法,所以判断的是===
,可以区分1和”1”。
2. 可以判断undefined、null,但无法处理NaN。
7.2 方式二:排序对比相邻元素
思路:先将数组排序,排序后相同的元素一定会在相邻的位置,然后对比相邻元素是否相同。
Array.prototype.unique2 = function () {
this.sort(); //先排序
var res = [this[0]];
for (var i = 1; i < this.length; i++) {
if (this[i] !== res[res.length - 1]) {
res.push(this[i]);
}
}
return res;
}
var arrs = var arrs = ["1", NaN, "2", null, "a", "2", "b", "a", "1", undefined, 1, 2, 5, 6, 9, 7, null, 4, 5, 5, 7,undefined, NaN];
console.log(arrs.unique2());
//[1, "1", "2", 2, 4, 5, 6, 7, 9, NaN, NaN, "a", "b", null, undefined]
特点:
1. 效率较第一种方式高。
2. 同样可以识别null、undefined,但无法处理Nan。
3. 因为对数组进行排序,所以无法保持数组原始顺序。
7.3 方式三:json的name判断相同元素
思路:创建一个新数组与一个json对象。利用json对象的name属性唯一的特性,将元素作为json对象的name,依次判断是否为相同元素。
Array.prototype.unique3 = function () {
var res = [];
var json = {};
for (var i = 0; i < this.length; i++) {
if (!json[this[i]]) {
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
}
var arrs = var arrs = ["1", NaN, "2", null, "a", "2", "b", "a", "1", undefined, 1, 2, 5, 6, 9, 7, null, 4, 5, 5, 7,undefined, NaN];
console.log(arrs.unique3());
//["1", NaN, "2", null, "a", "b", undefined, 5, 6, 9, 7, 4]
特点:
1. 对于undefined、null、NaN都可以正确识别。
2. 数字1和字符串”1”无法区分。
8 数组排序
一比较有意思的排序展示
http://jsdo.it/norahiko/oxIy/fullscreen
8.1 快速排序
var quickSort = function (arr) {
if (arr.length <= 1) return arr;
var midIndex = Math.floor(arr.length / 2);
var midValue = arr[midIndex];
var midArr = [midValue];
var left = [],
right = [];
arr.forEach(function (item, index) {
if (index == midIndex) return;
if (midValue > item)
left.push(item);
else if (midValue < item)
right.push(item);
else midArr.push(item);
}, this);
return quickSort(left).concat(midArr, quickSort(right));
};
var ss = [6, 4, 3, 89, 0, 6, 4, 4, 8, 0, 56, 213, 48];
console.log(quickSort(ss));
参考阮一峰
9 数组的转换
9.1 字符串与字符数组
9.1.1 字符串转为字符数组
方式1:正则表达式
var arr=str.match(/./g);
方式2:split方法
var arr = str.split('');
9.1.2 字符数组转为字符串
var str = arr.join('');
10 伪数组
- 有length属性。
- 按索引方式获取数据。
- 不具有数组的方法。但可使用for循环遍历。
- 常见的伪数组有
- arguments
- etElementsByTagName
- document.childNodes
- …
伪数组转化为数组
var arr = Array.prototype.slice.call(obj);
不适用IE8-
es6方法
var arr = Array.from(objList)
11 判断数组
判断数据类型的常用方式:
- typeof,这里数组是Object类型,使用typeof操作符返回”object”,故不能使用。
- instanceof:可以判断数组,但当页面存在框架时,在父页面对子页面的Array对象进行判断时,返回false,因为两个框架的Array指向不同。
- 原型链方法:
arr.constructor===Array
,存在兼容问题。 - 通用方法:
function isArray(o) {
return Object.prototype.toString.call(o) === ‘[object Array]‘;
}
12 数组特性
12.1 元素个数与length属性
数组元素个数与length属性并非一直匹配的,length可写,而后push元素会在数组最大索引的基础上设置索引。
var arr = [];
arr.length = 5;
console.log(arr.length); //5
arr[7] = 'test';
console.log(arr.length); //8 //实际上arr内只有一个元素,即index为7的'test'
console.log(3 in arr); //false 不存在索引为3的元素。所以当数组中存在空档时,不会自动创建索引。