深入理解JavaScript之数组

JavaScript是一种专门为于网页交互而设计的一门脚本语言主要有以下三个部分组成:

  • ECMAScript:提供和语言功能。
  • 文档对象模型(DOM):提供访问和操作网页的方法和接口。
  • 浏览器对象模型(BOM):提供与浏览器交互的方法和接口。

数组是一种类列表对象,它的原型中提供了遍历和修改元素的相关操作。JavaScript 数组的长度和元素类型都是非固定的。因为数组的长度可随时改变,并且其数据在内存中也可以不连续,所以 JavaScript 数组不一定是密集型的,这取决于它的使用方式。


Arrays数组

在js中,除了Object外,最常见的可能就是数组了,js的数组的每一项可以保存任意类型的值,而且数组的大小是根据数组内部数据的自动增加或减少而动态调整的。

创建数据有两种方式

  • 使用Array构造函数
  • 使用字面量表示法
1
2
3
var colors = new Array() //使用Array构造函数

var color = ['red','blue','green'] //使用字面量表示法

检测数组

如果是在一个网页或者一个全作用域里,可以使用instanceof
但是如果网页中存在iframe框架时,就会有两个全局作用域,在两个框架中的Array就会有不同的构造函数,那么instanceof就会为失效。

1
if(value instanceof Array){} //前提:在一个网页或者一个全作用域

最常用的是ES5新增方法Array.isArray()方法

1
if(Array.isArray(value)){}

转换方法

比较常用的转换方法是

  • toString(把数组转化为字符串显示)
  • join (把数组各项合并为字符串,中间的分隔符自定义)
1
2
3
4
5
var arr =  [1,2,3,4,5]
var arrStr = arr.toString() // "1,2,3,4,5"
typeof arrStr // 输出 string

var arrJoin = arr.join('*') // arrJoin = "1*2*3*4*5"

栈方法

栈是一种数据结构,规定栈里的项遵循先进后出的原则。
数据中主要的栈方法有两种:

  • push方法
  • pop方法

push方法是在数组的尾部增加数据项,返回增加数据项后数据的长度。
pop方法是在数据尾部移除数据项,返回移除的数据项。

1
2
3
4
5
var arr = [1,2,3,4,5],
popResult

arr.push(10) // arr = [1,2,3,4,5,10]
popResult = arr.pop() // popResult = 10; arr = [1,2,3,4,5]

队列方法

有栈方法,自然有队列方法。
常见的队列方法有

  • shift方法
  • unshift方法

shift方法是在数据头部移除数据项,返回被移除的数据值
unshift方法是在数据头部增加数据项,返回增加数据项后数组的长度

1
2
3
4
var arr = [0,1,2,3,4,5]

var result = arr.shift() // result = 0 arr = [1,2,3,4,5]
var num = arr.unshift(-1) // num = 6 arr=[-1,1,2,3,4,5]

重排序方法

常见的重排序方法有两种

  • reverse方法
  • sort方法

reverse方法会对数组里的数据项从尾到头反转顺序排列

1
2
var arr = [1,3,2]
var newArr = arr.reverse() // newArr = [2,3,1]

sort方法会对数据里的数据项进行顺序排序,但是会把数据项里的元素全部转化为字符串进行比较,即使数组里面是数值,这样就会导致你可能会得到不想要的结果

1
2
var arr = [1,3,2,12]
var newArr = arr.sort() // newArr = [1,12,2,3]

上例中,数字12要大于数字2,然而都转化为字符串之后再比较时,会先取字符串第一位并转化为ASCII码进行比较,如果第一位相同则比较第二位……
所以,字符串"12"中,取第一位为"1",在ASCII码值为49,而"2"的ASCII码值为50,因此上例中 '2' > '12'

查询方法

常见的查询方法有

  • indexOf
  • lastIndexOf

indexOf方法接受两个参数,

  1. 查找的值(查找时为严格相等,相当于===操作符的预算方式)
  2. 开始查找的位置

返回值:

  1. 如果查找到,则返回当前值在数组的索引值(位置)
  2. 如果没有找到,则返回-1

indexOflastIndexOf查找方式相同,只是lastIndexOf查找位置是从数组尾部向头部计算的

1
2
3
4
5
6
7
var arr = [1,'1',{a:1}]

arr.indexof(1) // 0
arr.indexo('1') // 1

//由于arr里是一个对象,参数里的{a:1}是新建的另一个对象,两个对象地址都不同,自然不相等
arr.indexof({a:1}) // -1

要想实现查找数组里的对象位置或者值,可以使用es6新增的find方法和findIndex方法

1
2
3
4
5
var arr = [1,'1',{a:1}]

arr.findIndex(function(item){return item === 1}) //0
arr.findIndex(function(item){return item === '1'}) //1
arr.findIndex(function(item){return item.a === 1}) //2

操作方法

常见的操作方法有

  • concat
  • slice
  • splice

concat方法主要的作用是连接多个数组,并返回连接之后的数组,即使多个数组的值相同,也不会合并成一个值。

1
2
3
4
5
var arr = [1,2]
var arr1 = [2,3,4]
var arr2 = [5]

arr.concat(arr1,arr2) // 返回值:[1,2,2,3,4,5]

slice方法是截取数组中的项组成一个新的数组,返回值就是一个新数组

传入参数:

  1. 截取的开始位置
  2. 截取的结束位置(可选,如果没有则默认为数组尾部位置)

如果传入的值为负数,则计算截取位置时: 截取开始位置 = 数组总长度-负数值
截取时包括开始位置的值,不包括结束位置的值

1
2
3
4
5
var arr = [1,2,3,4,5]

var newArr = arr.slice(2) // newArr = [3,4,5]
var newArr1 = arr.slice(1,3) // newArr = [2,3] 在这里只包括了arr[1],并没有包括arr[3]
var newArr2 = arr.slice(-1) // newArr2 = [5]

splice方法是个常见的删除中间数组值的方法,当然除了删除,还有插入,替换功能

作为删除方法时转入2个参数:

  1. 截取开始位置索引
  2. 截取结束位置索引

作为替换和插入方法时转入3个参数:

  1. 插入位置索引
  2. 0(是否删除从当前位置起第0个的值)
  3. 需要插入或替换的值(可传入多个)

splice始终返回一个数组,数组中包括被删除的项,如果没有删除,则返回空数组
splice删除时,即包含开始索引的值,也包含结束索引的值。
splice插入时,会从传入的位置插入,当前位置的数自动后移

1
2
3
4
5
6
7
var arr = [1,2,3,4,5]

arr.splice(1,3) // 返回值:[2,3,4]

var arr1 = arr.splice(1,0,'J','Q','K') //返回值 []; arr1 = [1,'J','Q','K',5]

var arr2 = arr.splice(1,3,'hello') //返回值 ['J','Q','K'];arr2 = [1,'hello',5]

迭代方法

所有的迭代方法都对数组中每一项运行给定的函数,根据得到的结果分为

  • every方法:每一项对给定函数运行的结果都为true,则返回布尔值true
  • some方法:任一一项对给定函数运行的结果都为true,则返回布尔值true
  • filter方法:返回一个数组,数组里面每一项的值都对给定函数运行为true.
  • forEach方法:没有返回值,适合遍历数组操作。
  • map方法:返回一个数组,数组里的值是给定函数运行的结果。
1
2
3
4
5
6
7
8
9

var arr = [1,3,5,7,9]

arr.every((item)=>{return item > 5}) // false
arr.some((item)=>{return item > 5}) // true
arr.filter((item)=>{return item > 5}) // [7,9]
arr.forEach((item)=>{return item > 5}) // undifined
arr.map((item)=>{return item > 5}) // [true, true, false, false, false]
arr.map((item)=>{return item + 1}) // [2,4,6,8,10]

归并方法

遍历数组所有的项,然后构建一个最终返回的值,方法主要有

  • reduce
  • reduceRight(从尾部开始遍历)

接受两个参数

  1. 指定的函数
    • 初始值或回调的返回值(如果没制定初始值,那么初始值就为数组的第一个值)
    • 当前值(数组正在处理的那个值)
    • 当前值的索引
    • 当前数组
  2. 初始值
1
2
3
4
5
6
7
8
9
// 数组去重
var arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
var result1 = arr.reduce((init, current)=>{

if(init.length===0 || init.indexOf(current) === -1){
init.push(current);
}
return init;
}, []); // [1,2,3,5,4]