JavaScript数组
数组的属性length
数组的属性length,不是只读的。通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。
如果设置的length比原先的值小,会移出设置长度之后的值;如果比length大,新增的每一项都会取得undefined值。如果设置的length不是一个自然数,会抛出错误。
1
2
3
4
5
6
var tmp = [1,2,3,4,5]
tmp.length = 4;
console.log(tmp);
tmp.length = 6;
console.log(tmp);
console.log(tmp[5],tmp[6])
数组的长度是有上限的,2的32次方,平常的开发中几乎不会碰到这种情况
数组里面的值,也可以用delete来删除的,它的值变为空,如果你去访问,返回undefined,数组的长度并没有改变
1
2
3
4
5
var tmp = [1,2,3,4,5]
delete tmp[1];
console.log(tmp)
console.log(tmp[1])
console.log(tmp.length)
检测数组
- instanceof
` if(value instanced Array) {} `
但是instanceof不一定能保证检测的结果一定正确,因为只要是在原型链上的都会返回true ,arr instanceof Object 也返回true
- 判断数据构造函数是不是数组
a.constructor == Array
以上两个方法也会有些问题,比方说在一个浏览器中嵌套多个iframe,你来回切换环境,有可能全局环境变化了,比方说constructor被重写了,得出来的值会出错
- Array.isArray() 返回Boolean类型
ECMAScript 5新增了Array.isArray()方法
对浏览器的兼容性有要求,使用低版本浏览器可能不支持,会报错
- Object.prototype.toString.call(arr)== [‘Object Array’] 可以确保方法能检测一定是数组,没有兼容性问题
首先看浏览器是否支持ES5,如果支持,使用isArray(), 判断isArray是否是一个function;如果不是使用第三种方法
1
2
3
4
5
6
7
8
9
10
//判断是否是数组
var arr = [1,2,3,4,5]
function isArray(value){
if (typeof Array.isArray === "function") {
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value) === "[object Array]";
}
}
console.log(isArrayFn(arr));// true
数组方法
转换方法
toLocalString():
toString(): 返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串
valueOf(): 返回原数组
join(): 接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串
栈方法
push():可接受任意数量的参数,把它们逐个添加到数组的末尾,并返回修改后数组的长度
pop():不接受参数,移除数组最后一项,然后返回移除的项
队列方法
shift():移除数组中的第一项,并返回该项,同时将数组长度减一,会改变原来的数组
unshift():在数组前端添加任意个项并返回新数组的长度,会改变原来的数组
重排序方法
reverse():反转数组项的顺序,返回经过排序后的数组
sort():返回经过排序后的数组,默认按升序排序,sort方法会调用每个数组项的toString()转换方法,然后比较得到的字符串的ascll码;即使是数值,比较的也是字符串;它还可以接收一个比较函数,指定排序。比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个相等,返回0,如果第一个参数应该位于第二个之后则返回一个整数
sort方法其实就是冒泡排序
sort排序存在性能问题,比方说一个数组,都是数字,已经是从小到大的排序了,最好的情况是排序次数是数组的长度;最坏的情况是一个数组本身是从大到小排序,需要从小到大排序,则需要比较的次数是数组长度的平方
如果你只是想反转数组原来的排序,使用reverse()要更快一些
var arr = [500, 200, 55]
sort方法的排序,每次都是从数组的第一项开始比较的
先拿出两项比较,如果大于0,交换位置并从第一项开始重新排序,如果小于或等于0,不交换位置,然后把数组的第二项和第三项排序,一旦交换了位置,就会从第一项开始重新排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var arrayNumber = [1, 2, 3];
arrayNumber.sort(function(a,b) {
if(a < b) {
return -1;
}else if(a > b) {
return 1
}else {
return 0;
}
})
// 简单写法
arrayNumber.sort(function(a, b) {
return b - a;// 降序
})
如果需要对比较大的数组进行排序,比方说已知数组中的数据是1-1000中的数字,可以把数组先分成两组,1-500,500-1000的两组,然后分别排序,再进行拼接
操作方法
concat():可以传任意个参数,该参数可以是一个数值,也可以是对象,或者数组,如果是数组,会将数组中的每一项添加到结果数组中,不会改变原来的数组,这个方法会先创建一个副本,所有的操作都是在副本中进行的
slice():接收一或两个参数,即要返回项的起始和结束位置;如果只有一个参数,返回从该参数的指定位置到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项(但不包括结束位置的项)。如果参数中有负数,则用数组长度加上该数来确定相应的位置,如果结束位置小于起始位置,则返回空数组。
这个方法不会改变原始数组。
splice:主要用途是像数组的中部插入项,有如下几种方法
- 删除:可以删除任意数量的项,只需指定两个参数:要删除的第一项的位置和要删除的项数
- 插入:可以向指定位置插入任意数量的项。只需提供3个参数:起始位置,0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四,第五,以至任意多个项
- 替换:可以向指定的位置插入任意数量的项,而且同时删除任意数量的项,只需指定3个参数:起始位置,要删除的项和要插入的任意数量的项。插入的项目不必与删除的项目相同
splice方法始终会返回一个数组,包含从原始数组中被删除的项,如果没有删除任何项,则返回要给空数组。
这个方法会改变原始数组
迭代方法
以下方法都不会修改数组中包含的值
他们的作用相同,都是根据你传进去的每一项去遍历,都有三个参数,当前项,当前索引,整个数组。区别只是返回值的不同
every(): 对数组中的每一项运行给定的函数,如果该函数对每一项都返回true,则返回true
filter():对数组中的每一项运行给定的函数,返回该函数会返回true的项组成的数组
forEach():对数组中的每一项运行给定的函数,这个方法没有返回值
map():对数组中的每一项运行给定的函数,返回每次函数调用的结果组成的数组
some():对数组中的每一项运行给定的函数,如果该函数中任意一项返回true,则返回true
位置方法
下面这两个方法都接收两个参数,第一个是要查找的项,第二个(可选)表示查找起点位置的索引
indexOf():从数组开头向后查找,返回要查找的项在数组中的位置
lastIndexOf():从数组的末尾开始向前查找,返回要查找的项在数组中的位置
归并方法
reduce():从数组第一项开始,逐个遍历到最后,然后构建一个最终返回的值
reduceRight():从数组最后一项开始,向前遍历到第一项,然后构建一个最终返回的值
它们都接收两个参数:一个在每一项上调用的函数和(可选的)作为归并基础的初始值。传给reduce()和reduceRight()的函数接收4个参数:前一个值,当前值,项的索引和数组对象。这个函数返回的任何值都会作为第一个参数自动传给下一项。第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二个参数是数组的第二项
这两个函数主要是遍历顺序不一样,其他完全相同
1
2
3
4
5
6
7
var tmp = [1,2,3,4,5]
var sum = tmp.reduce(function (prev, cur, index, array) {
console.log(prev, cur, index, array)
return prev + cur
})
console.log(sum) // 15