封面图片来自Google
javascript
除了Object外,Array类型恐怕是Js中最经常使用的类型了前端
Js中数组的特色:java
建立数组的两种基本方式:构造函数Array()
和数组字面量[]
es6
/ * 构造函数 */
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方法,后面提到)编程
arr[idx]
方括号访问索引是以 0
开始的,以以前的 arr5
为例:数组
arr5[0] // 3 访问第一项
arr5[2] // {'name':'Leo'}
arr5[2]='edit' // 修改第三项数据为 ’edit‘
arr5[3]='add' // 新增第四项为 'add'
复制代码
Js数组的 length
属性是可读可写的,因此能够经过数组的 length
属性对其进行加长和移除项的操做浏览器
var tryArrLen=['data1',2,'data3']
tryArrLen.length // 3
tryArrLen.length=4 //数组新增一项,该项默认会为'undefined'
tryArrLen[5]='add' //数组新增一项,值为'add'
tryArrLen[tryArrLen.length]='data' //利用'length'属性向数组末尾添加元素
tryArrLen.length=2 //数组项减小到2,会删除第三项'data3'
tryArrLen[2] //此时再次访问第三项,也会为undefined,不过缘由是第三项已经被删除了
复制代码
var tryArrLen2=[1,2,3]
tryArrLen2[99]=100 //在第一百项添加一个数据 '100'
复制代码
此时 tryArrLen2.length=?
,答案是 100
,而且从第四项到第九十九项的数据都是空位,简单的理解为 undifined
。bash
具体来讲ES6的数组方法都把空位做为undefined
,而ES5数组方法中对空位的处理不太统一,参考数组的空位函数
var tryArrLen3=[1,2,3]
tryArrLen3.length=4294967296 // RangeError: Invalid array length
复制代码
Js数组最多能够包含 4294967295
项,超出了,报 RangeError
。ui
一个经典问题:如何检测某个对象是否是数组?
方法 | 不足 |
---|---|
arr isInstanceOf Array |
arr 必须和Array 在同一个全局做用域。多个全局环境时候(好比frame)就是妖怪。 |
Array.isArray(arr) |
对老版本浏览器兼容性很差 |
Object.prototype.toString.call(arr) == "[Object Array]"
复制代码
任何一个对象上调用 Object
原生的 toString()
方法,都会返回一个
[Object NativeConstructorName]
的字符串。
注意!!前提是
Object.prototype.toString()
自己也没有被修改过,由于其也有可能被修改...
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
复制代码
和toString()
基本相同,区别在于能够指定以什么字符串进行拼接
let arr=[1,2,3]
arr.join('+') // "1+2+3"
复制代码
push()
:接收任意个数的参数,按顺序添加到数组末尾pop()
:移除数组的最后一项(不接收参数),并返回该项,数组length-1
shift()
:移除数组的第一项(不接收参数),并返回该项,数组length-1
unshift()
:接收任意个数的参数,按顺序添加到数组前端将这四个方法进行组合就能够实现栈和队列的基本操做
/* 栈 */
push()+pop()
unshift()+shift()
/* 队列 */
push()+shift()
unshift()+pop()
复制代码
反转数组的顺序
默认调用每一个数组项的toString
方法,在进行排序。能够接收一个比较函数做为排序的参数
比较函数接收两个形参,表示数组中相邻的两个数,好比val1
,val2
。 返回值能够为
val2
以前val2
以后因此在比较函数内能够写排序逻辑,比较经常使用的:
function compare(val1,val2){
return val2-val1
}
...
arr.sort(compare) //降序排列
复制代码
建立当前数组的副本,并将接收的参数添加到副本的末尾,并返回一个新数组(没有参数即返回副本自己)
若concat()
的参数是数组,则会将参数数组的每一项(考虑当数组中的项是数组或对象的状况)添加到结果数组末尾。 若参数不是数组类型,则是简单添加到结果数组的末尾。
对数组进行切片操做,不改变原数组,返回一个新数组。
接收一个或两个数字参数:
[ 参数 , arr.length)
[ 参数1 , 参数2 )
当参数为负数时,则能够将length
加上该参数来肯定其正数位置。即负数从数组末尾算起(最后一位为 -1
,依次类推)
splice()
接收 2
个或者 2+n
个参数,返回值永远为一个数组,包含从原数组中删除的项(没有删除返回空数组)。splice()
操做会改变原数组。
splice( startPos, delCount , el1,el2,..eln )
复制代码
startPos
: 起始位置delCount
:(从起始位置起)删除的项数el
:(可选参数)插入或者替换的项主要能够实现数组的删除、插入和替换操做。
startPos
、delCount
startPos
,且 delCount=0
,后面跟须要插入的若干个元素startPos
,delCount
为(从 startPos
开始)要替换的元素个数,后面给须要替换的若干个元素。(注:delCount
能够和参数中元素个数不同,多余的就变为删除或者插入操做)。indexOf()
:从前日后找lastIndexOf()
:从后往前找都接收两个参数:待查找的项和(可选)查找的起始位置。 返回值为待查找的项在数组中的位置,没有找到则返回-1
注:查找时候使用的是
===
进行判断
迭代方法都不可使用break
或者continue
进行中断。
forEach()
:对数组每一项运行指定函数,没有返回值map()
:对数组每一项运行指定函数,返回return
的结果组成的新数组。filter()
:对数组每一项运行指定函数,返回return
的结果为true
的成员组成的新数组。every()
:对数组每一项运行指定函数,若指定函数对每一项都return
的值为true,则返回true
,不然false
some()
:对数组每一项运行指定函数,若指定函数对任意一项return
的值为true,则返回true
,不然false
reduce()
:从前到后遍历reduceRight()
:从后到前遍历都接收4个参数:前一个值
,当前值
,项的索引
,数组对象
。每次return
的值会传递到下一次处理的第一个参数中。
参考: