封面图片来自Google
除了Object外,Array类型恐怕是Js中最常用的类型了
Js中数组的特点:
- 有序表
- 可以存储任意类型数据
- 数组长度是动态的(可以随数据的添加自动增长内容)
1、创建数组
创建数组的两种基本方式:构造函数Array()
和数组字面量[]
/ * 构造函数 */var arr1 = new Array() // 创建一个空数组var arr2= new Array(3) // 创建一个length为3的空数组var arr2= new Array('ok') // ['ok']var arr2= new Array(3,5) // [3,5]var arr3= Array('ok') // ['ok'] 数组的创建省略new,效果也是相同的,区别于对象/* 数组字面量 */var arr4=[] //空数组var arr5=[3] // [3]var arr5=[3,'array',{ 'name':'Leo'}] // [3,'array',{ 'name':'Leo'}]/* 不要像下面这样!! */var arrNotRecommend1=[1,2,] //会创建一个2项或者3项的数组var arrNotRecommend2=[, , , , ] //会创建一个4项或者5项的数组 //原因是老版本(IE8-)的浏览器在数组字面量的实现上存在BUG复制代码
对于Array()
创建数组有些缺陷(坑),因为给的参数个数(0,1,2+)不同都会导致Array()
有不同的行为,所以一般建议用数组字面量,或者Array.of()
(ES6方法,后面提到)
2、访问和设置数组的成员
2.1、使用 arr[idx]
方括号访问
索引是以 0
开始的,以之前的 arr5
为例:
arr5[0] // 3 访问第一项arr5[2] // { 'name':'Leo'}arr5[2]='edit' // 修改第三项数据为 ’edit‘arr5[3]='add' // 新增第四项为 'add'复制代码
2.2、length属性 :数据项个数
Js数组的 length
属性是可读可写的,所以可以通过数组的 length
属性对其进行加长和移除项的操作
var tryArrLen=['data1',2,'data3'] tryArrLen.length // 3tryArrLen.length=4 //数组新增一项,该项默认会为'undefined'tryArrLen[5]='add' //数组新增一项,值为'add'tryArrLen[tryArrLen.length]='data' //利用'length'属性向数组末尾添加元素tryArrLen.length=2 //数组项减少到2,会删除第三项'data3'tryArrLen[2] //此时再次访问第三项,也会为undefined,不过原因是第三项已经被删除了复制代码
2.3、length属性骚操作
var tryArrLen2=[1,2,3]tryArrLen2[99]=100 //在第一百项添加一个数据 '100'复制代码
此时 tryArrLen2.length=?
,答案是 100
,并且从第四项到第九十九项的数据都是空位,简单的理解为 undifined
。
具体来说ES6的数组方法都把空位作为undefined
,而ES5数组方法中对空位的处理不太统一,参考
var tryArrLen3=[1,2,3]tryArrLen3.length=4294967296 // RangeError: Invalid array length复制代码
Js数组最多可以包含 4294967295
项,超出了,报 RangeError
。
3、数组检测
一个经典问题:如何检测某个对象是不是数组?
3.1、常规操作
方法 | 不足 |
---|---|
arr isInstanceOf Array | arr 必须和Array 在同一个全局作用域。多个全局环境时候(比如frame)就是妖怪。 |
Array.isArray(arr) | 对老版本浏览器兼容性不好 |
3.2、骚操作
Object.prototype.toString.call(arr) == "[Object Array]"复制代码
任何一个对象上调用 Object
原生的 toString()
方法,都会返回一个
[Object NativeConstructorName]
的字符串。 注意!!前提是
Object.prototype.toString()
本身也没有被修改过,因为其也有可能被修改...
4、转换方法
4.1、对象方法
valueOf()
:返回数组本身toString()
:返回数组的字符串表示。每个值以字符串表示,并以逗号,
拼接toLocaleString()
:和toString()
基本相同,区别在于输出的是本地化的、特定语言环境的字符串
/* 将下列代码修改 'zh-cn'为其他语言,运行一下,你就明白了 */var array1 = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')];var localeString = array1.toLocaleString('zh-cn', {timeZone: "UTC"});console.log(localeString);// expected output: "1,a,12/21/1997, 2:12:00 PM",// This assumes "en" locale and UTC timezone - your results may vary复制代码
4.2、join()
和toString()
基本相同,区别在于可以指定以什么字符串进行拼接
let arr=[1,2,3]arr.join('+') // "1+2+3"复制代码
5、栈和队列方法
push()
:接收任意个数的参数,按顺序添加到数组末尾pop()
:移除数组的最后一项(不接收参数),并返回该项,数组length-1
shift()
:移除数组的第一项(不接收参数),并返回该项,数组length-1
unshift()
:接收任意个数的参数,按顺序添加到数组前端
将这四个方法进行组合就可以实现栈和队列的基本操作
/* 栈 */push()+pop()unshift()+shift()/* 队列 */push()+shift()unshift()+pop()复制代码
6、重排序方法
6.1、reverse()
反转数组的顺序
6.2、sort()
默认调用每个数组项的toString
方法,在进行排序。可以接收一个比较函数作为排序的参数
比较函数接收两个形参,表示数组中相邻的两个数,比如val1
,val2
。 返回值可以为
- 负数,即'val1'排在
val2
之前 - 0,不改变排序
- 正数,'val1'排在
val2
之后
所以在比较函数内可以写排序逻辑,比较常用的:
function compare(val1,val2){ return val2-val1 }... arr.sort(compare) //降序排列复制代码
7、操作方法
7.1、concat()
创建当前数组的副本,并将接收的参数添加到副本的末尾,并返回一个新数组(没有参数即返回副本本身)
- 数组浅拷贝
- 合并数组
若concat()
的参数是数组,则会将参数数组的每一项(考虑当数组中的项是数组或对象的情况)添加到结果数组末尾。 若参数不是数组类型,则是简单添加到结果数组的末尾。
7.2、slice()
对数组进行切片操作,不改变原数组,返回一个新数组。
接收一个或两个数字参数:
- 1个参数:返回从该位置到数组末尾的切片,即
[ 参数 , arr.length)
- 2个参数:返回参数1位置到参数2位置-1的切片,即
[ 参数1 , 参数2 )
当参数为负数时,则可以将length
加上该参数来确定其正数位置。即负数从数组末尾算起(最后一位为 -1
,依次类推)
7.3、splice()
splice()
接收 2
个或者 2+n
个参数,返回值永远为一个数组,包含从原数组中删除的项(没有删除返回空数组)。splice()
操作会改变原数组。
splice( startPos, delCount , el1,el2,..eln )复制代码
startPos
: 起始位置delCount
:(从起始位置起)删除的项数el
:(可选参数)插入或者替换的项
主要可以实现数组的删除、插入和替换操作。
- 删除 只需指定两个参数
startPos
、delCount
- 插入 指定
startPos
,且delCount=0
,后面跟需要插入的若干个元素 - 替换 指定
startPos
,delCount
为(从startPos
开始)要替换的元素个数,后面给需要替换的若干个元素。(注:delCount
可以和参数中元素个数不一样,多余的就变为删除或者插入操作)。
8、位置方法
indexOf()
:从前往后找lastIndexOf()
:从后往前找
都接收两个参数:待查找的项和(可选)查找的起始位置。 返回值为待查找的项在数组中的位置,没有找到则返回-1
注:查找时候使用的是
===
进行判断
9、迭代方法
迭代方法都不可以使用break
或者continue
进行中断。
forEach()
:对数组每一项运行指定函数,没有返回值map()
:对数组每一项运行指定函数,返回return
的结果组成的新数组。filter()
:对数组每一项运行指定函数,返回return
的结果为true
的成员组成的新数组。every()
:对数组每一项运行指定函数,若指定函数对每一项都return
的值为true,则返回true
,否则false
some()
:对数组每一项运行指定函数,若指定函数对任意一项return
的值为true,则返回true
,否则false
10、归并方法
reduce()
:从前到后遍历reduceRight()
:从后到前遍历
都接收4个参数:前一个值
,当前值
,项的索引
,数组对象
。每次return
的值会传递到下一次处理的第一个参数中。
11、
参考:
- 《JavaScript高级编程》