数组

数组的概念

js 有内置的构造函数 Array

构造出的对象被称为 数组对象 ,或者直接简称 数组

let a1 = new Array(1, 2, 3, 4)

let a2 = new Array(1, 2, 3.14, 'hello', {name:'白月黑羽', genda:'男'})

数组的主要作用是 存储 数据对象。

我们可以把数组想象为 一连串的储物格,就像下面这样

其中每个储物格里面都可以存储 任何类型 的数据

注意:是任何类型的数据, 数字(整数/小数)、字符串、函数、对象 等等 都可以。


由于数组经常被用到,所以js还可以使用如下简便语法构建

let a1 = [1, 2, 3, 4]

let a2 = [1, 2, 3.14, 'hello', {name:'白月黑羽', genda:'男'}]

方括号 用来表示一个数组, 里面存储的数据,通常被称之为数组的 元素 ,每个元素之间用逗号隔开。

数组里面也可以存储另一个数组对象,如下

var a = [1, 2, 3.14, 'hello', [7,8,9] ]

最后一个元素 就是 另外的一个数组对象 [7,8,9]



数组中元素的个数可以通过 length 属性获取

比如

var a = [1, 2, 3.14, 'hello', [7,8,9] ]
a.length // 结果是5

索引

可以用元素 索引 的方式取出里面的元素


数组的 索引 和 字符串索引的用法是 类似的。

比如上面的数组,其索引如下所示

数组每个元素的索引是从0开始的

var a = [1, 2, 3.14, 'hello', [7,8,9] ]
a[0]    // 就是 1
a[1]    // 就是 2
a[4]    // 就是 [7,8,9]

切片 slice

js 中的 字符串 和 数组 ,都有 slice 方法可以进行切片。

什么是切片, 形象的说,好像用刀切出其中的一部分

比如我要把

var hello = '刘总你好啊'

这个字符串切出其中 你好 这部分内容,

假想我们手里有把刀,要从下面的字符串中切出 你好,就应该在箭头所示的地方切两刀,就得到 你好 这个 子字符串了

那么我们看看这两刀 对应的索引的位置。

如果用正数表示就是 2 和 4 , 可以用 hello.slice(2,4) 来得到该字符串。


注意:切片 开始索引 是切片开始的元素的 索引, 而 结束索引 是切片结束的元素的 索引 + 1


大家可以运行如下代码看看

var hello = '刘总你好啊'
console.log(hello.slice(2,4))

就像Python中的 切片表达式 hello[2:4]


切片也可以用负数表示位置, 就是 -3 和 -1 , Python中可以用 hello.slice(-3,-1) 得到该字符串。

大家可以运行如下代码看看

console.log(hello.slice(-3,-1))

字符串切片前面的索引是切片开始的元素的 索引,后面的索引是切片结束的元素的 索引 + 1



可以看出,slice方法有两个参数, 分别代表切片 前后 两刀 的位置

如果 后面这一刀的位置是 末尾 ,可以省略这个参数

比如

var hello = '刘总你好啊'
console.log(hello.slice(2))

结果就是 你好啊

hello.slice(2) 效果等同于 hello.slice(2,hello.length)



数组的切片也和字符串类似,想象用刀去切取其中的一部分,该在哪里下刀,就使用哪里的索引

var a = [1, 2, 3.14, 'hello', [7,8,9] ]
a.slice(0,3)     // 结果是 [ 1, 2, 3.14 ]
a.slice(3,5)     // 结果是   ['hello', [7,8,9] ]
a.slice(3)       // 结果也是 ['hello', [7,8,9] ]

a.slice(-1)      // 结果是 [ [ 7, 8, 9 ] ]
a.slice(-1)[0].slice(0,2)   // 结果是   [7,8]   为什么? 自己想一想

console.log(a)      
// 结果还是 [1, 2, 3.14, 'hello', [7,8,9] ] 
// 上面对a的切片操作是产生新的对象,并不会改变a指向的对象

改变数组内容

和我们前面学过的其它数据类型不同,数组对象有个特点,它的内容是 可以变化的

末尾添加 push

push方法就会改变数组的内容,在后面添加一个元素。

比如

var a = [1, 2, 3.14, 'hello']  

// push 之后,a就变成了 [1, 2, 3.14, 'hello', '你好']
a.push('你好')
console.log(a)


// 继续添加 ,a就变成了 [1, 2, 3.14, 'hello', '你好', [7,8]]
a.push([7,8])
console.log(a)

// 可以添加多个元素
a.push(7,8,'白月黑羽')
console.log(a)

注意,push 方法的返回值是 push后,数组的长度,而不是新的数组对象。

如果你这样写

var a = [1, 2 ]  
var b = a.push(88)
console.log(b)

就会发现b的值为3

末尾取出元素 pop

如果我们要从数组 末尾取出元素 一个元素,就可以使用 pop 方法。

pop 方法的返回值 是 取出来的元素

注意,取出后,该元素就从数组中删除了。

比如

var a = [1, 2, 3.14, 'byhy.net']  

// 取出索引为3 的元素,也就是第4个元素
var ele = a.pop()  // 返回值是 'byhy.net'

// 取出后,a数组对象内容就变成了 [ 1, 2, 3.14]
console.log(a)

// 而取出的元素赋值给变量 ele, ele 的内容就是 'byhy.net'  
console.log(ele)

开头取出元素 shift

如果我们要从数组 开头取出元素 一个元素,就可以使用 shift 方法。

shift 方法的返回值 是 取出来的元素

注意,取出后,该元素就从数组中删除了。

比如

var a = [1, 2, 3.14, 'byhy.net']  

// 取出索引为3 的元素,也就是第4个元素
var ele = a.shift()  // 返回值是 1

// 取出后,a数组对象内容就变成了 [ 2, 3.14, 'byhy.net' ]
console.log(a)

// 而取出的元素赋值给变量ele, ele的内容就是 1l
console.log(ele)

改变单个元素

比如

var a = [1, 2, 3.14, 'hello', [7,8,9] ]

a[0] = '你好'
console.log(a)

执行上面的代码,可以发现,最后数组变量 a 的内容变成了

['你好', 2, 3.14, 'hello', [7, 8, 9]]

如果这样写

var a = [1, 2, 3.14, 'hello', [7,8,9] ]

a[4][2] = '你好'
console.log(a)

就改变了数组里面的数组 的内容,a就变成了

[1, 2, 3.14, 'hello', [7, 8, '你好']]

数组的元素也可以填写变量,比如

var a1 = [7, 8, '你好']
var a = [1, 2, 3.14, 'hello', a1]
console.log(a)

结果a的值是

[1, 2, 3.14, 'hello', [7, 8, '你好']]

数组的元素还可以填写表达式,js引擎会自动计算结果,放入数组中,比如

var var1 = 100
var a = [1, 2, var1*3 + 20, 'hello', [7, 8, '你好']]
console.log(a)

结果a的值是

[1, 2, 320, 'hello', [7, 8, '你好']]

指定位置删除 splice

splice 方法可以 删除 数组的一段内容

spliceslice 多一个字母,作用却大不一样

如果 传入一个参数,如下:

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

// 把从索引2开始,后面的元素全部删除
list1.splice(2)  // 返回值为 [ 2, 3, 4, 5 ]

// 结果list1 变成 [ 0, 1 ]

splice 的返回值是被删除的部分, 运行后 list1 值变化为剩余部分


如果 传入2个参数,如下:

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

// 把从索引2开始,连续删除 3 个 元素
list1.splice(2,3) // 返回值为 [ 2, 3, 4 ]

// 结果list1 变成 [ 0, 1, 5 ]

指定位置替换 splice

splice 方法也可以 替换 数组的一段内容。

替换就是 删除后再插入内容, splice从第3个开始,以后的参数都是要插入的元素。

比如:

如果我们要把下面的数组

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

其中 1,2,3 换成 a,b,c , 该怎么做呢?

当然可以这样

list1[1] = 'a'
list1[2] = 'b'
list1[3] = 'c'

但是一个个的写有点麻烦,数组支持 这样一部分内容 整体替换

list1.splice(1,3, 'a','b','c')  //返回值为 [  1, 2, 3 ]

// 结果 list1 就变成了 [0, 'a', 'b', 'c', 4, 5]

这种写法称之为 切片赋值

切片赋值 甚至支持 替换的元素 比 被替换的元素 多, 像这样

var list1 = [0, 1, 2, 3, 4, 5]
list1.splice(1,3, 'a','b','c','e','f','g','h')

结果 list1 就变成了 [0, ‘a’, ‘b’, ‘c’, ‘e’, ‘f’, ‘g’, ‘h’, 4, 5]

指定位置插入 splice

如果我们 不是要在后面 添加一个元素, 而是在 指定位置插入一个元素怎么办?

还是可以使用 splice 方法,第2个参数 删除个数 设置为 0

比如

var a = [1, 2, 3.14, 'byhy.net']  

// 插入到索引0的位置,也是插到第1个元素的位置上
// a数组内容就变成了 ['你好', 1, 2, 3.14, 'byhy.net']
a.splice(0, 0,  '你好')
console.log(a)


// 插入到索引2的位置,也是插到第3个元素的位置上
// a数组内容就变成了 ['你好', 1, '黑羽',  2, 3.14, 'byhy.net']
a.splice(2, 0, '黑羽')
console.log(a)

熟悉python的朋友可能发现这个splice 和python的切片赋值比较相似

数组元素倒过来 reverse

reverse方法将数组元素倒过来

var var1 = [1,2,3,4,5,6,7]
var1.reverse()
console.log(var1)

运行结果 var1就变成了 [7, 6, 5, 4, 3, 2, 1]


reverse 方法的返回值也是 原来的数组内容 ,也就是 [1,2,3,4,5,6,7]

获取元素索引 indexOf

indexOf 方法返回 参数对象 在数组 中的位置,也就是索引

var var1 = [1,2,3,4,5,6,7,5]
var pos = var1.indexOf(5)
console.log(pos)

运行后,发现idx的值为4 , 也就是说 5这个元素在数组 var1 中 索引为4


如果参数指定数据 不在数组中, indexOf 返回 -1

所以, indexOf 也可以用来检查数组中是否有某个元素


indexOf 方法 的第二个参数,用来指定 查找起始位置 ,比如

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

// 第2个参数 6, 表示从 索引 6 的位置开始往后查找
var pos = var1.indexOf(5,6)
// 返回的是第2个5的 的索引  7
console.log(pos)

indexOf的一个常用的场景是删除数组中等于某个数值的元素

比如要删除一个数组中值为5的元素

let array = [2, 5, 9];

// 先获取值为5的元素的索引
let index = array.indexOf(5);

// 然后再调用splice方法删除
if (index > -1) {  
  array.splice(index, 1); 
}

检查是否包含 includes

数组的 includes 方法 返回数组中是否包含参数指定的数据

返回值为 true 表示存在,false 表示不存在

如下

let array1 = [1, 2, 3]

array1.includes(2) // 结果为 true

let pets = ['cat', 'dog', 'bat']

pets.includes('cat') // 结果为 true

pets.includes('at')  // 结果为 false

includes 方法 的第二个参数,用来指定 查找起始位置 ,比如

let pets = ['cat', 'dog', 'bat']

pets.includes('cat',1 ) // 结果为 false

清空数组

  • 方法1 :变量赋值

如果我们是想让某个变量对应的数组为空,可以这样:

var arr1 = ['a','b','c','d','e','f'];
arr1 = [];

这种方式,其实是创建了一个新空数组, 原来的数组如果没有引用会被删除。

  • 方法2 :设置数组长度
var arr1 = ['a','b','c','d','e','f'];
arr1.length = 0

设置数组长度为0,这样一个数组里面的内容就会被清空

  • 方法3 :使用splice
var arr1 = ['a','b','c','d','e','f'];
arr1.splice(0, arr1.length) 

拼接字符串 join

下面的数组里面包含了员工薪资

var salary = [
  'Mike : 12900',
  'John : 22900',
  'Jerry : 16900',
  'Jack : 32900'
]

如果我们想把所有人的薪资打印在一行,中间用两个竖线 || 隔开,像这样

Mike : 12900 || John : 22900 || Jerry : 16900 || Jack : 32900

怎么办?可以使用 数组的 join 方法。

join 就是用参数里面的字符串连接数组里面的元素,返回值就是拼接后的字符串

console.log(salary.join(' || '))

相当于把参数数组里面的字符串连接在一起, 中间加上指定的连接符 ||


如果 我们想把薪资打印出来,一个人一行,就可以这样

console.log(salary.join('\n'))

多个变量同时赋值

我们可以像下面这样把 数组 中的元素直接赋值给变量

var x1, x2, x3, x4
[x1, x2, x3, x4] = [1,2,3,4]
console.log(x1, x2, x3, x4)   

这种方式的术语叫: 解构赋值(Destructuring assignment )


解构赋值时,如果变量的个数 多于 等号右边的 值个数,有的变量值就是 undefined。

[x1, x2, x3, x4] = [1,2,3]
console.log(x1, x2, x3, x4)

函数返回数组

函数的返回值可以是一个数组,像这样

function func1(var1,var2){
  return  [var1**2, var2**2]
}

当我们有多个数据对象需要在函数里面返回的时候,就可以放到数组中。

const 定义变量

自从 ES2015 (ES6) 后,支持 const 关键字 变量定义

如下

const PI = 3.141592653589793
const author = '白月黑羽'
const arr1 = [1,2,3]

const 定义的变量,必须在定义时就赋值,后续不能重新赋值

也就是说: const 变量指向的对象 定义后就不能改变

PI = 3.14  // const变量重新赋值会报错
author = '白月黑羽' //值相等也不行

但是const定义的变量 指向的对象内容变化是可以的

arr1 = [3,4] // const变量重新赋值会报错
arr1[0] = '白月黑羽' // 变量对象本身值可以变

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况

map方法

经常有这样的需求,对数组中的每个元素进行同样的处理,产生另外一个数组

比如:一个数组A里面有一系列的数字,需要产生另外一个数组B,元素是数组A相应的每个数字的平方

当然可以写循环实现

但是还有更简单的方法,就是使用数组的 map方法,如下所示

const array1 = [1, 4, 9, 16];

function square(x) {return x ** 2} 

// pass a function to map
const map1 = array1.map(square);

console.log(map1);

map的参数是一个函数对象,就是对每个元素的处理函数