JavaScript中的数组学习
1、数组的定义
var arr = ['a','b']
var arr = new Array('a','b')
var arr = new Array(4)
1.1、数组下标越界
- js中规定,数组下标越界会返回
undefined
,而不会报错。(go会panic)
var arr = ['a','b']
arr[1] // b
arr[2] // undefined
1.2、数组长度
- 数组的
length
属性表示数组的长度。(go中使用len()函数)
var arr = ['a','b','c']
console.log(arr.length) // 3
1.3、数组更改项内容
- 通过下标获取数组某项再赋予新值即可。
arr[1] = '只因'
- 当获取的下标超过数组的长度时,会自动创建新的项,即数组变长了。
var arr = ['a','b']
// 更改项
arr[1] = '只因'
console.log(arr) // (2) ['a', '只因']
// 下标超过原数组长度
arr[4] = '坤'
console.log(arr) // (5) ['a', '只因', empty × 2, '坤']
区别: go数组下标越界会panic,同时go不允许修改数组的长度
1.4、数组类型的检测
typeof
数组的类型为object
,并不是Array
- 可使用
Array.isArray()
来检测,返回结果为布尔值
2、数组的常用方法
pop(),shift(),push(),unshift()
删除项与插入项splice()
,替换指定项slice()
,截取数组join()
和split()
concat()
,多个数组连接,不改变原数组reverse()
,数组置反,改变原数组indexOf()
和includes()
,数组中是否存在某元素
2.1、数组的删除项与插入项
- 删除:
pop()
删除尾部,并返回删除内容,shift()
删除头部,并返回删除内容。 - 插入:
push()
尾部插入新项,unshift()
头部插入新项
var arr = ['a','b','c']
// pop
var p = arr.pop()
console.log(arr,p) // ['a','b'],'c'
// shift
var s = arr.shift()
console.log(arr,s) // ['b'],'a'
// push
arr.push('d','e')
console.log(arr) // ['b','d','e']
// unshift
arr.unshift('r')
console.log(arr) // ['r','b','d','e']
2.2、splice()
替换指定项
数组.splice(i,j,arr...)
,从第i个项开始(i不是下标),将后面连续的j个项,替换成arr,同时以数组形式返回被替换的内容
var arr = ['a','b','c']
var a = arr.splice(1,1,'d','e','f')
console.log(arr) // (5) ['a', 'd', 'e', 'f', 'c']
console.log(a) // ['b']
2.2.1、splice()
实现插入项和删除项
var arr = ['a','b','c','e','f','g']
// 插入
arr.splice(1,0,'只因','坤')
console.log(arr) // ['a', '只因', '坤', 'b', 'c', 'e', 'f', 'g']
// 删除
arr.splice(3,3)
console.log(arr) // ['a', '只因', '坤', 'f', 'g']
2.3、slice()
截取数组
slice(a,b)
,从下表a开始,截取到下标b,但不包含下标b。[a,b):左包含,右不包含
b是可选的,也可以为负数
。当b不填时,表示从a到最后;当b为负数时,表示从a到倒数第几项。slice()
并不会改变原数组,只是获得基于原数组截取的一个子数组。
var arr = ['a','b','c','d']
var a = arr.slice(1,3)
console.log(arr) // ['a', 'b', 'c', 'd'] 原数组并未改变
console.log(a) // ['b', 'c']
// b为负数
var b = arr.slice(1,-2)
console.log(b) // ['b']
// b不填
var c = arr.slice(1)
console.log(c) // ['b', 'c', 'd']
2.4、join()
和split()
join('a')
,将数组以'a'
作为分隔符连接成字符串。(数组转字符串)split('a')
,将字符串以'a'
作为分隔符切割成数组。(字符串转数组)
var arr = ['1','2','3','4']
var s = arr.join('a')
console.log(s) // 1a2a3a4
var a = s.split('a')
console.log(a) // ['1', '2', '3', '4']
2.5、concat()
多个数组连接。
concat(arr1,arr2...)
,将多个数组进行连接,形成新数组。并不会改变原数组
var arr1 = ['1','2','3']
var arr2 = ['4','5']
var arr3 = ['6','7']
var arr = arr1.concat(arr2,arr3)
console.log(arr) // ['1', '2', '3', '4', '5', '6', '7']
2.6、reverse()
,数组置反
reverse()
,数组置反。不会形成新数组,直接改变原数组。
var arr = ['a','b','c']
arr.reverse()
console.log(arr) // ['c', 'b', 'a']
2.7、indexOf()
和includes()
,数组中是否存在某元素
indexOf('a')
,搜索数组中'a'
元素,返回第一个元素的下标;若不存在则返回-1
。includes('a')
,判断数组中是否存在'a'
元素,存在返回true
,反之返回false
var arr = ['a','b','c','a']
console.log(arr.indexOf('a')) // 0
console.log(arr.indexOf('d')) // -1
console.log(arr.includes('a')) // true
console.log(arr.includes('d')) // false
3、数组为引用类型
var arr = arr1
,arr1
赋值给arr
的其实是arr1
指向的内存地址,而不是arr1
值的副本。即当arr1
后续发生改变时,arr
也会随着改变。
var arr1 = ['a','b','c']
var arr = arr1
console.log(arr) // ['a', 'b', 'c']
arr1.push('d')
console.log(arr) // ['a', 'b', 'c', 'd']
引用类型与基本类型比较
包含类型 | 值传递时(赋值) | 作相等(==)比较时 | |
---|---|---|---|
基本类型 | Number 、string 、boolean 、undefined | 传递值的副本 | 比较值是否相等 |
引用类型 | object 、Array | 传递内存地址 | 比较内存地址是否相等 |
4、数组的深浅拷贝
浅拷贝
:只拷贝数组的第一层,不拷贝数组中的项是引用类型的。深拷贝
:拷贝数组的所有层。使用递归进行拷贝。
4.1、数组的浅拷贝
数组的元素中不含有引用类型的值
// 浅拷贝
var arr = ['a','b','c']
var arr1 = []
for (var i = 0;i < arr.length;i++) {
arr1.push(arr[i])
}
console.log(arr1) // ['a', 'b', 'c']
console.log(arr1 == arr) // false 故:arr1 与 arr的内存地址不同
数组的元素中含有引用类型的值
var arr = ['a','b',['c','d']]
var arr1 = []
for (var i = 0;i < arr.length;i++) {
arr1.push(arr[i])
}
console.log(arr1) // ['a', 'b', Array(2)]
console.log(arr1[2] == arr[2]) // true 故:arr1[2] 与 arr[2]的内存地址相同,并未实现真正意义上的拷贝。
4.2、数组的深拷贝
- 数组的深拷贝,本质上与浅拷贝相似,不同的在于深拷贝使用递归多次执行浅拷贝,从而达到多层数组的拷贝。
- 判断每个元素的类型,是引用类型的才执行递归。
// 深拷贝
var arr = [1,2,3,[4,5,[6,7]]]
function fun(n){
var res = []
for (var i = 0; i < n.length;i++){
if (Array.isArray(n[i])){
res.push(fun(n[i]))
}else{
res.push(n[i])
}
}
return res
}
var a =fun(arr)
a.push(8)
console.log(arr) // [1,2,3,[4,5,[6,7]]]
console.log(a) // [1,2,3,[4,5,[6,7]],8]