JavaScript数组

89 阅读5分钟

目录:

1.数组介绍

2.创建数组

3.数组的增删改查

4.数组变换

一、数组介绍

1.数组对象

  • 数组是一种特殊的对象

  • JS没有真的数组,只是用对象来模拟数组

2.JS数组不是典型数组

典型数组的特点

  • 其他开发语言中,数组是真正数组

  • 特点如下

    1. 元素数据类型相同

    2. 使用连续的内存存储

    3. 通过数字下标获取元素

  • 内存图

ced4f3e05ff0c7b8765e9b248af2cc8.png

JS的数组特点

  • JS数组可以放任何类型的数据

    1. 元素的数据类型可以不同,数组里可以有对象

    2. 内存不一定是连续的(如果是对象,那就是随机存储)

    3. 不能通过数字下标,而是通过字符串下标获取元素

    4. 这意味着数组可以有任何key

  • 比如

let arr = [1,2,3]
arr['xxx'] = 1 // arr = [1,2,3,1] 最后一个1的下标为'xxx'

  • 内存图

c63abdd62c21b6585832460109c7759.png

二、创建一个数组

1.新建

  • let arr = [1,2,3]

  • let arr = new Array(1,2,3)

  • let arr = new Array(3) 创建了一个长度为3的数组,不是数组里有个3

2.转化

  • let arr = '1,2,3'.split(',') // [1,2,3]

  • let arr = '123'.split('') //[1,2,3]

  • Array.form('123') ES6新增,把不是数组的东西尝试变成数组

3.伪数组

  • let divList = document.querySelectorAll('div')

  • 伪数组的原型链没有数组的原型,例如pop/push等API

  • 换句话说,如果一个数组中没有数组的共有属性,那它就是伪数组

  • 得到了伪数组可以通过Array.form转化成数组,不然会很麻烦

4.合并两个数组,得到一个新数组

  • arr1.concat(arr2) 不会改变原来的数组

5.截取一个数组的一部分

  • arr1.slice(1) 从第二个元素开始截取

  • arr1.slice(0) 全部截取,通常用来复制一个数组

  • 注意:JS只提供浅拷贝

三、数组增删改查

1.删元素

和对象一样 不推荐

 let arr = ['a','b','c']
 delete arr = ['0']
 arr //[empty,'b','c']
  • 比较神奇的是,数组长度并没有改变,这样会变成一个稀疏数组,会有很多bug

直接该length的值 不推荐

let arr = [1,2,3,4,5]
arr.length = 1
arr //[1]
  • 改length属性会把数组下标对应后面的数全部删了,很容易让你的代码出bug

1.1 删除头部元素

  • arr.shift() //arr 被修改,并返回被删除的元素 原来的数组没有了这个被删除的元素

1.2 删除尾部元素

  • arr.pop() //arr 被修改,并返回被删除的元素原来的数组没有了这个被删除的元素

1.3 删除中间的元素

  • arr.splice(index,1) 删除index的一个元素,index表示下标

  • arr.splice(index,1,'x') 删除index的一个元素,并在删除位置添加一个'x'

  • arr.splice(index,1,'x','y') 删除index的一个元素,并在删除位置添加一个'x','y'

2.查看所有元素

2.1 查看所有属性名

let arr = [1,2,3,4,5];arr.x = 'xxx'
Object.keys(arr)
// 0:1,1:2,2:3,3:4,4:5,x:'xxx'

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

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

2.3 要自己让i0增长到length-1

for (let i = 0; i<arr.length; i++){
console.log(`${i}:${[i]}`)
}

2.4 也可以用forEach/map等原型上的函数

arr.forEach(function(item,index){
    console.log(`${index}:${item}`)
})
  • for循环forEach的区别在于,for循环支持break,可以设置中止遍历,Each只能遍历完

  • for循环是关键字,forEach是函数

2.4 补充 我确实forEach没怎么看懂

  • 我自己先写一个,然后未来有问题再回来看
function forEach(array,fn){
    for(let i = 0; i<array.length; i++){
        fn(array[i], i , array)
    }
}
  • forEachfor访问array的每一项

  • 对每一项调用fn(array[i], i , array)这个函数

  • array这个参数,是规定的,每次遍历都会整个数组包含进去,用的时候很少,一般就用前两个参数就行

3.查看单个属性

3.1 跟对象一样

let arr = [111,222,333]
arr[0]
// 111

3.2 索引越界

  • arr[arr,length] //undefined

  • arr[-1] //undefined

  • 任何不存在的下标,读出来都是undefined

3.3 举例

for(let i = 0; i<=arr.length; i++){
    console.log(arr[i].toString())
}

//报错:Cannot read property 'toString' of undefined
因为arr.length=3 arr的下标就到2 读到3的时候就是undefined

3.4 查找某个元素是否在数组里

  • arr.indexOf(item) 如果存在该元素,就返回它的索引号,如果没有该元素就返回-1

3.5 使用条件查找元素

  • arr.find(item => item % 2 === 0) 找到第一个偶数后停止,并返回该元素

3.6 使用条件查找元素的索引

  • arr.findIndex(item => item % 2 === 0) 找到第一个偶数的索引后停止

4. 增加数组中的元素

4.1 在尾部增加元素

  • arr.push(newItem) ,在原数组最后添加一个新元素,修改原数组,返回新数组的长度

  • arr.push(item1,item2) 在原数组最后添加两个新元素,修改原数组,返回新数组的长度

4.2 在头部增加元素

  • arr.unshift(newItem) 在原数组最前面添加一个新元素,修改原数组,返回新数组的长度

  • arr.unshift(item1,item2) 在原数组最前面添加两个新元素,修改原数组,返回新数组的长度

4.3 在中间添加元素

  • arr.splice(index,0,'x')index处,插入元素'x'

  • arr.splice(index,0,'x','y')

5.修改数组中的元素

5.1 反转顺序

  • arr.reverse() 反转并修改原数组

5.2 自定义排序

        let arr3 = [1, 2, 3, 4, 5]

        arr3.sort(function (a, b) {
            if (a > b) {
                return -1
            } else if (a === b) {
                return 0
            } else {
                return 1
            }
        })

        console.log(arr3);  //[5,4,3,2,1]

  • 如果a>b 返回-1 则数字越大越靠前,如果a>b 返回1 则数组越小越靠前

四、数组变换

1.map

map(['牛肉', '土豆', '鸡', '玉米'], 加工) 
=> ['汉堡', '薯条', '炸鸡', '爆米花']
把数组内元素通过加工, 把值调出来
  • n变n

  • 想把一个数组内的数变成它们自身的平方

let arr = [1,2,3,4,5]
arr.map(item => item*item)
=> [1,4,9,16,25]

2.filter

filter(['汉堡', '薯条', '炸鸡', '爆米花'], 素的) 
=> ['薯条', '爆米花']
把数组中是素的调用出来
  • n 变 少

  • 想只要数组里的偶数

let arr = [1,2,3,4,5,6]
arr.filter(item => item % 2 === 0)
=> [2,4,6]

3.reduce

reduce(['汉堡', '薯条', '炸鸡', '爆米花'], 吃了) 
=> 屎
把数组中的元素给吃了, 然后返回一个值, 这个返回值也是reduce的返回值
  • n 变 1

  • 想把数组中的每个数相加,最后得到一个结果

let arr = [1,2,3,4,5,6]
arr.reduce((sum,item) => {
return sum + item
},0)
=> 21
  • 0 是初始值,遍历数组的每一个值,你可以要求对他们做什么事

  • reduce能代替mapfilter,几乎是万能的

4.实例

  • 把数组内的数字,转化成周几,例如0就是周天
let arr = [0, 1, 2, 2, 3, 3, 3, 
let arr2 = arr.map(item => {
    if (item === 0) {
        return '周' + '日'
    } else if (item === 1) {
        return '周' + '一'
    } else if (item === 2) {
        return '周' + '二'
    } else if (item === 3) {
        return '周' + '三'
    } else if (item === 4) {
        return '周' + '四'
    } else if (item === 5) {
        return '周' + '五'
    } else if (item === 6) {
        return '周' + '六'
    }
}, [])
console.log(arr2) // ['周日', '周一', '周二', '周二', '周三', '周三', '周三', '周四', '周四', '周四', '周四','周六']
  • 找出所有大于六十分的成绩
let scores = [95, 91, 59, 55, 42, 82, 72, 85, 67, 66, 55, 91]
let scores2 = scores.filter(item => item >= 60)
console.log(scores2) //  [95,91,82,72,85,67,66, 91]
  • 算出所有奇数之和
let scores = [95, 91, 59, 55, 42, 82, 72, 85, 67, 66, 55, 91]
let sum = scores.reduce((sum, n) => {
    if (n % 2 === 1) {
        return sum + n
    } else {
        return sum + 0
    }
}, 0)
console.log(sum) // 奇数之和:598