基本操作
声明
数组里可以存放任何类型的数据
// 使用构造函数创建
const arr = new Arrary(0, 1, 2, 3)
// 字面量方式创建
const newArr = [0, 1, 2, 3]
获取元素
根据下标获取,从 0 开始
const arr = [0, 1, 2, 3, 4]
// 获取第三个元素
cosnole.log(arr[2]) // 2
const arr1 = [
[1, 2],
[2, 3],
]
console.log(arr[0]) // [1,2]
获取数组长度
根据 arr.length
获取数组长度
const arr = [0, 1, 2, 3, 4]
console.log(arr.length) // 5
arr[10] = 2
console.log(arr.length) // 10,6-9会填充为empty
console.log(arr[7]) // undefined
注意
使用构造函数创建数组时, 如果只填写一个为 number 类型的值,就会将此数组填充为对应长度的数组
const arr = Array.from({ length: 10 })
console.log(arr.length) // 10
在 es6 以后,使用 Array.of
可以解决此问题
const arr = Array.of(10)
console.log(arr.length) // 1
console.log(arr) // [10]
类型检测
可以使用 Array.isArray
检测一个数据是否是数组
console.log(Array.isArray([])) // true
console.log(Array.isArray("")) // false
console.log(Array.isArray({})) // false
console.log(Array.isArray(1)) // false
console.log(Array.isArray(false)) // false
转换为字符串
可以使用 数组.toString
将数组转换为字符串
console.log([].toString()) // ''
console.log([1, 2, 3].toString()) // '1,2,3'
后端需要传递一个 id 字符串时,可以使用此方法转换
可以使用数组 String(数组)
来转换
console.log(String([1, 2, 3, 4])) // '1,2,3,4'
可以使用数组.join('拼接的字符')
来自定义用什么符号拼接为字符串
console.log([1, 2, 3, 4].join("-")) // '1-2-3-4'
console.log([1, 2, 3, 4].join(",")) // '1,2,3,4'
其他类型数据转换为数组
字符串可以使用字符串.split()
转换为数组
console.log("1,3,4,6".split(",")) // [1,3,4,6]
元素中有 length 属性时,可以使用 Array.from(元素)
转换
const string = "whbbit.cn"
console.log(Array.from(string))
// ['w', 'h', 'b', 'b', 'i', 't','.', 'c', 'n']
Object 也可以使用此特性转换:
const obj = {
0: 'whbbit.cn',
1: 'wxw'
}
console.log(Array.from(obj)) // []
obj.length = 2
console.log(Array.from(obj)) // ['whbbit.cn', 'wxw']
Arrar.from()有第二个参数,是对第一个元素的操作
<div>1</div>
<div>2</div>
<script>
let divs = document.querySelectorAll("div")
// 将div元素的color设置为红色
Array.from(divs, (item) => {
item.style.color = "red"
return item
})
</script>
扩展运算符
数组拼接
const className = ["js", "css", "html"]
const numbers = [1, 2, 3]
console.log([...numbers, className])
函数传参
参数数量不确定时可以使用展开语法将所有参数接收到一个数组中
function sum(...rest) {
return rest.reduce((s, v) => (s += v), 0)
}
sum(1, 2, 3, 4)
dom 节点操作
<div>1</div>
<div>2</div>
<script>
let divs = document.querySelectorAll("div")
// 直接进行遍历会报错
// divs.map(item => console.log(item)) // 报错
// 需要转换为数组进行遍历
;[...divs].map((item) => {
console.log(item)
})
</script>
解构赋值
不使用解构赋值
const arr = ["wxw", 23]
const name = arr[0]
const age = arr[1]
使用解构赋值
const [name, age] = ["wxw", 23]
过滤某个值
const [, age] = ["wxw", 23]
结合扩展运算符
const [name, ...rest] = ["wxw", 23, "whbbit.cn"]
赋值默认值
function show([name, year, site = 10]) {
console.log(name, year, site) // 'wxw', 23, 10
}
show(["wxw", 23])
数组方法
数组元素添加
let arr = [0, 1]
// 数组后追加
arr[arr.length] = [2]
arr[arr.length] = [3]
arr = [...arr, 4]
arr.push(5) // 返回值是数组长度
// 在数组前添加
arr.unshift(-1) // 返回值是数组长度
arr = [-2, ...arr]
数组删除元素
使用 pop()弹出数组最后一个元素,会改变原数组
const arr = [0, 1]
const val = arr.pop()
console.log(val) // 1
使用 shift() 弹出数组第一个元素,会改变原数组
const arr = [0, 1]
const val = arr.shift()
console.log(val) // 0
数组填充
console.log(Array.from({ length: 3 }).fill(0)) // [0,0,0]
在指定位置填充
// 从下标为1填充至下标为3,不包含3
console.log([1, 2, 3, 4].fill("wxw", 1, 3))
// [1, 'wxw', 'wxw', 4]
splice
会改变原数组,返回值为受改变的元素
const arr = [0, 1, 2, 3, 4]
// 第一个参数从下标为几开始 第二个参数截取几位,第三个/n个参数:替换的元素
const change = arr.slice(1, 2)
console.log(change) // [1,2]
slice
不会改变原数组,返回值为受改变的元素
const arr = [0, 1, 2, 3, 4]
// 第一个参数从下标为几开始 第二个参数到下标为几结束
let change = arr.slice(1, 2)
console.log(change) // [2]
// 从0截取到末尾
change = arr.slice()
console.log(change) // [0,1,2,3,4]
// 从1截取到末尾
change = arr.slice(1)
console.log(change) // [1,2,3,4]
案例:移动数组元素方法
function move(array, from, to) {
if (from < 0 || to >= array.length) {
console.log("参数错误")
return
}
const newArray = [...array]
const item = newArray.splice(from, 1)
newArray.splice(to, 0, ...item)
return newArray
}
const array = [0, 1, 2, 3]
console.log(move(array, 1, 3))
清空数组
赋值一个新数组,内存地址更改为新数组的地址。对原有内存地址数据没有改变
let array = [0, 1, 2, 3, 4]
const w = array
array = []
console.log(array) // []
console.log(w) // [0, 1, 2, 3, 4]
长度设置为 0,对原有内存地址数据进行操作。其他引用该地址的数据也会清空
const array = [0, 1, 2, 3, 4]
const w = array
array.length = 0
console.log(array) // []
console.log(w) // []
const array = [0, 1, 2, 3, 4]
array.splice(0)
const array = [0, 1, 2, 3, 4]
// eslint-disable-next-line no-empty
while (array.pop()) {}
数组拆分/合并
拆分
const str = "1,2"
const arr = str.split(",")
合并 concat() 或 扩展运算符
const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
arr1.concat(arr2)
复制指定元素至指定位置 copyWithin()
查找数据
indexOf 和 lastIndexOf
indexOf
从数组左侧开始查找对应元素。元素存在就返回当前元素在数组中第一次出现的位置,不存在就返回-1
const arr = [1, 2, 3, 4]
console.log(arr.indexOf(2)) // 1
console.log(arr.indexOf(8)) // -1
lastIndexOf
从数组右侧开始查找对应的元素。元素存在就返回当前元素最后一次出现的位置,不存在就返回 -1
const arr = [1, 2, 3, 4, 3]
console.log(arr.lastIndexOf(3)) // 4
console.log(arr.lastIndexOf(6)) // -1
indexOf 和 lastIndexOf会进行类型匹配
const arr = [1, 2, 3, 4, "5"]
console.log(arr.indexOf(5)) // -1
console.log(arr.lastIndexOf(5)) // -1
indexOf 和 lastIndexOf可以传递第二个参数,表示从第几个元素开始查找
返回值还是该元素在数组中出现的第一次或最后一次
const arr = [1, 2, 3, 4, 2]
console.log(arr.indexOf(2, 1)) // 1
console.log(arr.indexOf(3, 1)) // 4
includes
查找对应的元素是否在对应的数组中,返回 boolean 类型
const arr = [1, 2, 3, 4, 5]
console.log(arr.includes(2)) // true
console.log(arr.includes(10)) // false
includes 实现原理
function includes(array, val) {
// eslint-disable-next-line no-unreachable-loop
for (const value of array) {
if (value === val)
return true
return false
}
}
const array = [1, 2]
console.log(includes(array, 2)) // true
const lesson = [{ name: "html" }, { name: "js" }, { name: "css" }]
console.log(lesson.includes({ name: "html" })) // false
// 内存地址不一致导致没有找到对应的元素
find 和 findIndex
find
find 可以传递一个回调函数,回调函数返回值为 true 时就返回找到第一个值,回调函数返回为 false 时就返回 undefined
const arr = [1, 2, 3]
console.log(arr.find(item => true)) // 1
console.log(arr.find(item => item === 2)) // 2
console.log(arr.find(item => item === "2")) // undefined
console.log(arr.find(item => item === 200)) // undefined
const lesson = [{ name: "html" }, { name: "js" }, { name: "css" }]
console.log(lesson.find(item => item.name === "html")) // {name: 'html'}
findIndex
findIndex 可以传递一个回调函数,回调函数返回值为 true 时就返回找到第一个值所在的位置,回调函数返回为 false 时就返回 -1
const lesson = [{ name: "html" }, { name: "js" }, { name: "css" }]
console.log(lesson.findIndex(item => item.name === "html")) // 1
自定义 find
function find(array, callback) {
for (const value of array) {
if (callback(value)) {
return value
}
}
return undefined
}
find([1, 2, 3, 4], item => item === 2) // 2
在原型链上定制 findValue 方法
// eslint-disable-next-line no-extend-native
Array.prototype.findValue = function (callback) {
for (const value of this) {
if (callback(value))
return value
}
return undefined
}
;[1, 2, 3, 4].findValue(item => item === 2) // 2
排序
sort
回调函数返回值小于 0 两者位置互换,大于 0 不变
const arr = [1, 3, 2, 4, 5]
// 从小到大排序
arr.sort((a, b) => a - b) // [1,2,3,4,5]
// 从大到小排序
arr.sort((a, b) => b - a) // [5,4,3,2,1]
let cart = [
{ name: "html", price: 20 },
{ name: "css", price: 25 },
{ name: "js", price: 30 },
]
// 按价格从小到大排
cart = cart.sort((a, b) => a.price - b.price)
// 按价格从大到小排
cart = cart.sort((a, b) => b.price - a.price)
sort 实现
function sort(array, callback) {
for (const n in array) {
for (const m in array) {
if (callback(array[n], array[m]) < 0) {
;[array[n], array[m]] = [array[m], array[n]]
}
}
}
return array
}
arr = sort([2, 3, 1], (a, b) => a - b)
arr = sort([2, 3, 1], (a, b) => b - a)
数组循环
for 循环
const lessons = [
{ name: "html", price: 20 },
{ name: "css", price: 25 },
{ name: "js", price: 30 },
]
for (let i = 0; i < lessons.length; i++) {
console.log(lessons[i])
}
// { name: "html", price: 20 }
// { name: "css", price: 25 }
// { name: "js", price: 30 }
for ... of
拿到的值是对应元素的值
const lessons = [
{ name: "html", price: 20 },
{ name: "css", price: 25 },
{ name: "js", price: 30 },
]
for (const lesson of lessons) {
lesson.click = true
}
console.log(lessons)
/**
[
{ name: "html", price: 20, click: true},
{ name: "css", price: 25, click: true},
{ name: "js", price: 30, click: true},
]
*/
为什么可以改变原数组呢?
这里的 lesson 是重新赋值的一个元素,可以改变原数组是因为这是直接改变内存地址中的值
const arr = [1, 2, 3]
for (let value of arr) {
value = 3
}
console.log(arr) // [1,2,3]
for ... in
拿到的值是对应元素的下标
const lessons = [
{ name: "html", price: 20 },
{ name: "css", price: 25 },
{ name: "js", price: 30 },
]
for (const index in lessons) {
console.log(lessons[index])
}
// { name: "html", price: 20 }
// { name: "css", price: 25 }
// { name: "js", price: 30 }
forEach
forEach 可以收两个参数,第一个参数是一个回调函数,第二个参数是 this 指向。回调函数可以接受三个参数,第一个是当先循环的元素,第二个是当前循环的下标,第三个元素是原数组
const lessons = [
{ name: "html", price: 20 },
{ name: "css", price: 25 },
{ name: "js", price: 30 },
]
lessons.forEach((item, index, lessons) => {
console.log(item, index, lessons)
})
interator 迭代器
const lessons = [
{ name: "html", price: 20 },
{ name: "css", price: 25 },
{ name: "js", price: 30 },
]
console.log(lessons.keys().next())
some & every
some
every
数组过滤
filter
返回符合条件的数据数组
const arr = [1, 2, 3]
console.log(arr.filter(item => item > 2)) // [3]
filter 实现
const arr = [1, 2, 3]
function filter(array, callback) {
const newArray = []
for (const value of array) {
if (callback(value) === true) {
newArray.push(value)
}
}
return newArray
}
const res = filter(arr, item => item > 2)
console.log(res) // [3]
map
返回一个操作后的数组
const arr = [1, 2, 3]
const newArr = arr.map(item => item + 2)
console.log(newArr) // [3,4,5]
reduce
reduce 接收两个参数,第一个参数为一个回调函数,第二个参数是初始值
回调函数第一个值是上一次回调函数的返回值,第一次调用时 reduce 没有传递第二个参数,就默认为数组的第一个参数,第二个参数有传值就为第二个参数传递的值
const arr = [1, 2, 3, 4, 5]
// eslint-disable-next-line array-callback-return
arr.reduce((pre, value, index, array) => {
console.log(pre, value)
})
/**
1,2
undefined, 3
undefined, 4
undefined, 5
*/
// eslint-disable-next-line array-callback-return
arr.reduce((pre, value, index, array) => {
console.log(pre, value)
}, 2)
/**
2,1
undefined, 2
undefined, 3
undefined, 4
undefined, 5
*/
arr.reduce((pre, value, index, array) => {
console.log(pre, value)
return 22
}, 2)
/**
2,1
22, 2
22, 3
22, 4
22, 5
*/
案例:统计元素出现次数
function arrayCount(array, item) {
return array.reduce((total, cur) => {
total += item === cur ? 1 : 0
return total
}, 0)
}
console.log(arrayCount([1, 2, 2, 2, 1, 1, 2], 2)) // 4
console.log(arrayCount([1, 2, 2, 2, 1, 1, 2], 1)) // 3
案例:获取元素中的最大值
function getMaxItem(array, item) {
return array.reduce((pre, cur) => (pre > cur ? pre : cur))
}
console.log(getMaxItem([1, 2, 3, 444, 555]))
案例:获取阅读次数最多的文章
function max(array) {
return array.reduce((pre, cur) => {
return pre.count > cur.count ? pre : cur
})
}
const article = [
{ title: "js基础", count: 100 },
{ title: "css基础", count: 200 },
{ title: "ts基础", count: 10 },
{ title: "html基础", count: 500 },
]
console.log(max(article))
案例:所有文章阅读总数
function count(array) {
return array.reduce((pre, cur) => (pre += cur.count), 0)
}
const article = [
{ title: "js基础", count: 100 },
{ title: "css基础", count: 200 },
{ title: "ts基础", count: 10 },
{ title: "html基础", count: 500 },
]
console.log(count(article))
案例:文章阅读总数大于 200 的文章名称
function getTitleByCount(array, count) {
return array
.reduce((arr, cur) => {
if (cur.count > count) {
arr.push(cur)
}
return arr
}, [])
.map(item => item.title)
}
const article = [
{ title: "js基础", count: 100 },
{ title: "css基础", count: 200 },
{ title: "ts基础", count: 10 },
{ title: "html基础", count: 500 },
]
console.log(getTitleByCount(article, 200))
案例: 数组去重
使用 reduce
const arr = [1, 2, 2, 2, 3, 34, 4, 1, 1, 1, 2, 3, 4, 5]
const result = arr.reduce((arr, cur) => {
if (!arr.includes(cur)) {
arr.push(cur)
}
return arr
}, [])
console.log(result)
使用扩展运算符和 Set
const arr = [1, 2, 2, 2, 3, 34, 4, 1, 1, 1, 2, 3, 4, 5]
const result = [...new Set([...arr])]
console.log(result)
评论区
评论加载中...