兔子零-A酱

欢迎来到我的个人博客,我会在这里记录下关于学习和生活的点点滴滴

JavaScript基础——数组

数组

数组是一种特殊的对象,JS其实没有真正的数组,只是用对象模拟数组

典型的数组:

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

但JS的数组不这样:

  • 元素的数据类型可以不同
  • 内存不一定是连续的(对象是随机存储的)
  • 不能通过数字下标,而是通过字符串下标

JS数组可以有任何key,比如:

let arr = [1,2,3]
arr['xxx'] = 1

创建数组

新建

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 = '1,2,3'.split('')
Array.from('123')

伪数组

没有数组共用属性的数组就是伪数组

let divList = document.querySelectorAll('div')

伪数组的原型链中并没有数组的原型

合并

// 合并两个数组
arr1.concat(arr2)
// 从第二个元素开始截取
arr.slice(1)
// 全部截取
arr.slice(0)
// JS只提供浅拷贝

删元素

let arr = ['a', 'b', 'c']
delete arr['0']
console.log(arr) // [empty, 'b', 'c']

删除头部元素

// arr 被修改,并返回被删元素
arr.shift()

删除尾部元素

// arr 被修改,并返回被删元素
arr.pop()

删除中间的元素

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

查看所有元素

查看所有属性名

let arr = [1, 2, 3, 4, 5]
arr.x = 'xxx'
Object.keys(arr)
Object.values(arr)
for (let key in arr) {
    console.log(`${key}:${arr[key]}`)
}

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

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

arr.forEach(function(item, index)  {
    console.log(`${index}: ${item}`)
})
function forEach(array, fn) {
    for(let i = 0; i < array.length; i++) {
        fn(array[i], i, array)
    }
}

查看单个属性

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

arr[arr.length] === undefined
arr[-1] === undefined

// 查找某个元素是否在数组里
arr.indexOf(item) // 存在返回索引,否则返回-1

// 使用条件查找元素
arr.find(item => item % 2 === 0) // 找第一个偶数

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

增加数组中的元素

在尾部加元素

// 修改arr,返回新长度
arr.push(newItem)
// 修改arr,返回新长度
arr.push(item1, item2)

在头部加元素

// 修改arr,返回新长度
arr.unshift(newItem)
// 修改arr,返回新长度
arr.unshift(item1, item2)

在中间添加元素

// 在 index 处插入'x'
arr.splice(index, 0, 'x')
arr.splice(index, 0, 'x', 'y')

修改数组中的元素

反转顺序

// 修改原数组
arr.reverse()

自定义顺序

arr.sort((a, b) => a - b)

数组变换

// map filter reduce都不会改变原数组

// 数组的每一项被cook后放入一个新数组内
map(['cow', 'potato', 'chicken', 'corn'], cook) => ['hamburger', 'french fries', 'chicken leg', 'popcorn']

filter(['hamburger', 'french fries', 'chicken leg', 'popcorn'], isVegetarian) => ['french fries', 'popcorn']

// 依次eat数组的每一项 最后得到reduce的返回值
reduce(['hamburger', 'french fries', 'chicken leg', 'popcorn'], eat) => 'shit'

let arr = [1, 2, 3, 4, 5, 6]
arr.map(item => item * item) // [1, 4, 9, 16, 25, 36]
arr.reduce((result, item) => { return result.concat(item * item) }, [])

arr.filter(item => item % 2 === 0) // [2, 4, 6]
arr.reduce((result, item) => {
    return result.concat(item % 2 === 1 ? [] : item)
}, [])

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

// sum是结果,sum的初始值是第二个参数,每次return的值作为第二次的sum
arr.reduce((sum, item) => { return sum + item }, 0)
  • map:n变n
  • filter:n变少
  • reduce:n变1

面试题

数据变换:

let arr = [
    { 名称: '动物', id: 1, parent: null },
    { 名称: '狗', id: 2, parent: 1 },
    { 名称: '猫', id: 3, parent: 1 }
]
// 以上数据变成对象
{
    id: 1,
    名称: '动物',
    children: [
        {
            id: 2,
            名称: '狗',
            children: null
        },
        {
            id: 3,
            名称: '猫',
            children: null
        }
    ]
}

arr.reduce((result, item) => {
    if (item.parent === null) {
        result.id = item.id
        result['名称']= item['名称']
    } else {
        result.children.push(item)
        delete item.parent
        item.children = null
    }
    return result
}, { id: null, children: [] })
上一篇文章 下一篇文章