JS数组

一、数组对象

  • 数组对象是一种特殊的对象

  • JS里其实没有真正的数组,只是用对象模拟数组(即伪数组)

JS的数组不是典型数组

典型数组:

  • 元素的数据类型相同
  • 使用连续的内存存储
  • 通过数字下标获取元素

image.png

JS用对象模拟数组

  • 元素的数据类型可以不同
  • 内存不一定是连续的(对象是随机存储的)
  • 不能通过数字下标,而是通过字符串下标
  • 这意味着数组可以有任何key,比如:let arr = [1,2,3] | arr['xxx']= 1

image.png

二、创建一个数组

  • 新建
let arr = [1,2,3]
let arr = new Array(1,2,3)
let arr = new Array(3)
复制代码
  • 转化
let arr = '1,2,3'.split(',') //通过字符串创建数组,用,号分隔
let arr = '123'.split('') //用空字符串把字符隔开
Array.from('123')  //把不是数组的东西尝试变成数组,需要满足两个条件:对象有'0''1''2'...下标;有length属性
复制代码

image.png

  • 伪数组

let divList = document.querySelectorAll('div')

伪数组的原型链中并没有数组的原型,比如push、pop等共同属性。没有数组共用属性的”数组”就是伪数组。 伪数组没有实际用意,每次遇到伪数组都用Array.from把它转换成数组。

创建一个数组(续)

  • 合并两个数组,得到新数组,不会改变原来的数组

arr1.concat(arr2)

image.png

  • 截取数组的一部分
arr1.slice(1) //从第二个元素开始切,不会改变原来的数据
arr1.slice(0) //常用于复制数组
复制代码

image.png

注意:JS提供浅拷贝

三、数组增删改查

删元素

  • delet方式
let arr = ['a','b','c']
delete arr['0'] //删除第一个元素
arr //[empty,'b','c'] 数组的长度并没有变,保留了原本元素的位置
delate arr[1]
delate arr[2] //[empty*3] 只有length,但没有对应的下标,称为‘稀疏数组’,多bug
复制代码

以上方法更适用于删除对象,不推荐于在数组中使用。

  • 改length删除法
let arr = [1,2,3,4,5];
arr.length = 2
arr //[1,2] 后面的数组元素都会被删除掉,且不会报错,实践中容易出bug
复制代码

!!注意:不要随便改length,以上两种方式:delete / 改length,都不推荐使用

推荐删元素的方式

  • 删除头部的元素
arr.shift() //arr被修改,并返回被删的元素
复制代码
  • 删除尾部的元素
arr.pop()  //arr被修改,并返回被删的元素
复制代码
  • 删除中间的元素
arr.splice(index,1)  //删除index中的1个元素

arr.splice(index,1,'x')  //并在删除位置添加'x'

arr.splice(index,1,'x','y') //并在删除位置添加'x','y'
复制代码

截屏2021-06-24 下午9.08.09.png

查看所有元素

  • 查看所有属性名
let arr = [1,2,3,4,5];arr.x = 'xxx'

Object.keys(arr)

for(let key in arr){console.log(`${key}:${arr[key]}`)}
复制代码

image.png

以上for in方法只适合查看对象,不适合数组,不推荐使用。

推荐for let查看方法

  • 查看数字(字符串)属性名和值

方法一:for循环

for(let i = 0; i < arr.lenght; i++){
   console.log(`${i}: ${arr[i]}`)
}  //在访问数组的时候,规定好下标必须是从0增长到length-1
复制代码

方法二:用forEach / map等原型上的函数

arr.forEach(function(item, index){
  console.log(`${index}: ${item}`)
}) 
复制代码

这两种方式的区别

1.for循环里有break和continue,而forEach是不支持的,一次全执行完。

2.for循环是关键字,没有函数作用域,只有块级作用域。forEach是函数,有函数作用域。

如何理解forEach

function forEach(array, fn){
  for(let i = 0; i<array.length; i++){
    fn(arry[i], i, array)
  }
}
复制代码

forEach用for访问array的每一项;

对每一项调用fn(arry[i],i,array),获取数组里的每一项并把每一项作为fn的参数传给fn。

查看单个属性

  • 下标法
let arr = [111,222,333]
arr[0]  //111
复制代码
  • 索引越界
arr[arr.length] === undefined
arr[-1] === undefined
// 任何不存在的下标去读都是undefined
复制代码

举例

let arr = [1,2,3,4,5,6,7]
for(let i = 0; i<= arr.lenght; i++){  //<=length是不允许的,length值是查不到,只能是length-1
    console.log(arr[i].tostring())
}
复制代码

image.png
Cannot read property 'toString' of underfined 意思是你读取了undefinedtoString属性,不是指toStringundefinedx.toString()其中x如果是undefined就会出现此报错。

查看单个属性(续)

  • 查找某个元素是否在数组里
arr.indexOf(item) //存在返回索引,否则返回-1
复制代码
  • 使用条件查找元素
arr.find(item => item %2 ===0)  //找第一个偶数
复制代码

但是find只会返回元素,不会返回下标,可使用findIndex,返回对应的元素的下标。

  • 使用条件查找元素的索引
arr.findIndex(item => item%2 ===0) //找第一个偶数的索引
复制代码

截屏2021-06-25 下午10.33.19.png

增加数组中的元素

  • 在尾部添加元素
arr.push(newItem)  //修改arr,返回新length
arr.push(item1,item2) //增加多项,修改arr,返回新length
复制代码
  • 在头部添加元素
arr.unshift(newItem)  //修改arr,返回新length
arr.unshift(item1,item2) //增加多项,修改arr,返回新length
复制代码
  • 在中间添加元素
arr.splice(index,0,'x') //在index处插入'x'
arr.splice(index,0,'x','y')
复制代码

截屏2021-06-25 下午11.04.58.png

修改数据中的元素

  • 替换法
let arr = [11,22,44]
arr[2] = 33  //把下标为2的位置替换成'33'
复制代码
  • 反转顺序
arr.reverse()  //修改原数组
复制代码

拓展:“如何把字符串反转顺序”

字符串是没有reverse的,需要把字符串先分开变成数组,再把数组反转顺序,最后合成字符串。

截屏2021-06-25 下午11.26.06.png

  • 自定义顺序
arr.sort((a,b)=> a-b)
复制代码

如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;

如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。

如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。

如果不设定compareFunction,JS默认为数值小的在前,数值大的在后,eg:1,2,3。但是实际到底谁小谁大,JS是不知道的,需要通过设定1,-1,0来让JS判断。

举例

截屏2021-06-26 上午12.12.01.png

数组变换

  • map

n变n

  • filter

n变少

  • reduce (可以代替map和filter,但是对新人不太友好,要多实践)

n变1

截屏2021-06-26 下午10.33.37.png

代码练习

image.png

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享