目录一、遍历类1. forEach2. map3. every4. some5. filter6. reduce7. reduceRight二、查找类1. find2. findIn
这篇文章会和你一起探究24+原生数组方法的内部实现,相信你看完一定会有属于自己不一样的收获。
基本使用:
forEach
一个日常用的非常多的遍历函数,你一定熟悉到不能再熟悉啦!这里我们着重看一些比较重要且容易忽略的点。mdn
undefiend
callback
函数,未初始化的项将被跳过(例如在稀疏数组上)。callback
的值是 forEach()
遍历到他们那一刻的值。举个小例子:
let demoArr = [ 1, 2, 3, 4, , 5 ]
demoArr.forEach((it, i) => {
if (i === 1) {
// 后添加进去的不会被访问到
demoArr.push(5)
} else if (i === 2) {
// 4将不会被访问到,而4-4会被访问到
demoArr.splice(3, 1, '4-4')
}
console.log(it)
})
代码实现:
Array.prototype.forEach2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
while (i < length) {
// 被删除的,新增的元素索引i不在数组内,所以不会被访问到
if (i in this) {
callback.call(thisCtx, this[ i ], i, this)
}
i++
}
}
同样用刚才的例子,改下后的输出是一样的
测试一把:
// 测试
let demoArr = [ 1, 2, 3, 4, , 5 ]
demoArr.forEach2((it, i) => {
if (i === 1) {
// 后添加进去的不会被访问到
demoArr.push(5)
} else if (i === 2) {
// 4将不会被访问到,相仿4-4会被访问到
demoArr.splice(3, 1, '4-4')
}
console.log(it)
})
基本使用:
map
方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。mdn
注意点:
callback
函数只会在有值的索引上被调用
// 注意索引为2的位置没有赋值
let arr = [ 1, 2, ,4, 5 ]
// 删除索引3
delete arr[3]
console.log(arr.map((it) => it * it))
// [ 1, 4, 25 ]
代码实现:
点击查看源码实现
Array.prototype.map2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
// map返回值是一个新的数组
let newArray = []
while (i < length) {
// 被删除的,未初始化的都不会被遍历到
if (i in this) {
newArray.push(callback.call(thisCtx, this[ i ], i, this))
}
i++
}
// 返回新的数组
return newArray
}
测试一把:
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let arr2 = arr.map2(function (it, i, array) {
console.log(it, i, array, this)
return it * it
}, { name: '前端胖头鱼' })
console.log(arr2)
基本使用:
every
方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。mdn
注意点:
// 举例
let emptyArr = []
// 空数组直接返回true
console.log(emptyArr.every((it) => it > 0)) // true
// 有未被赋值的
let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]
// 删除元素
delete arr[7]
console.log(arr.every((it) => it >= 0)) // true
代码实现:
点击查看源码实现
Array.prototype.every2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
// 空函数不会走进循环
while (i < length) {
// 只要有一个值不符合callback预期就返回false
if (i in this && !callback.call(thisCtx, this[ i ], i, this)) {
return false
}
i++
}
return true
}
测试一把:
还是拿例子做测试
let emptyArr = []
console.log(emptyArr.every2((it) => it > 0)) // true
let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]
delete arr[7]
console.log(arr.every2((it) => it >= 0)) // true
基本使用:
some
方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean
类型的值。 mdn
注意点:
callback
只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。举个例子
let emptyArr = []
// 空数组直接返回false
console.log(emptyArr.some((it) => it > 0)) // false
let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]
// 还没有遍历前把-1删除了,唯一小于0的值不存在了,即返回false
delete arr[7]
console.log(arr.some((it) => it < 0)) // false
代码实现:
点击查看源码实现
Array.prototype.some2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
while (i < length) {
// 只要有一个元素符合callback条件,就返回true
if (i in this && callback.call(thisCtx, this[ i ], i, this)) {
return true
}
i++
}
return false
}
测试一把:
let emptyArr = []
// 空数组直接返回true
console.log(emptyArr.some2((it) => it > 0)) // false
let arr = [ 0, 1, 2, 3, 4,, 5, -1 ]
delete arr[7]
console.log(arr.some2((it) => it < 0)) // false
console.log(arr.some2((it) => it > 0)) // true
基本使用:
filter
方法创建一个新数组, 其包含通过所提供函数测试的所有元素。 mdn
注意点:
filter
为数组中的每个元素调用一次 callback
函数,并利用所有使得 callback
返回 true
或等价于 true
的值的元素创建一个新数组。callback
只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。callback
测试的元素会被跳过,不会被包含在新数组中。
// 索引为5的位置,没有初始化值,不会被遍历
let arr = [ 0, 1, 2, -3, 4,, 5 ]
// 删除掉最后一个元素
delete arr[6]
// 过滤出大于0的值
let filterArr = arr.filter((it) => it > 0)
console.log(filterArr) // [ 1, 2, 4 ]
代码实现:
点击查看源码实现
Array.prototype.filter2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let newArray = []
let i = 0
while (i < length) {
if (i in this && callback.call(thisCtx, this[ i ], i, this)) {
newArray.push(this[ i ])
}
i++
}
return newArray
}
测试:
// 索引为5的位置,没有初始化值,不会被遍历
let arr = [ 0, 1, 2, -3, 4,, 5 ]
// 删除掉最后一个元素
delete arr[6]
// 过滤出大于0的值
let filterArr = arr.filter2((it) => it > 0)
console.log(filterArr) // [ 1, 2, 4 ]
基本使用:
reduce
方法对数组中的每个元素执行一个由您提供的reducer
函数(升序执行),将其结果汇总为单个返回值 mdn
这个函数稍微复杂一些,我们用一个例子来看一下他是怎么用的。
const sum = [1, 2, 3, 4].reduce((prev, cur) => {
return prev + cur;
})
console.log(sum) // 10
// 初始设置
prev = initialValue = 1, cur = 2
// 第一次迭代
prev = (1 + 2) = 3, cur = 3
// 第二次迭代
prev = (3 + 3) = 6, cur = 4
// 第三次迭代
prev = (6 + 4) = 10, cur = undefined (退出)
代码实现:
点击查看源码实现
Array.prototype.reduce2 = function (callback, initValue) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
let pre = initValue
let i = 0
const length = this.length
// 当没有传递初始值时,取第一个作为初始值
if (typeof pre === 'undefined') {
pre = this[0]
i = 1
}
while (i < length) {
if (i in this) {
pre = callback(pre, this[ i ], i, this)
}
i++
}
return pre
}
测试:
const sum = [1, 2, 3, 4].reduce2((prev, cur) => {
return prev + cur;
})
console.log(sum) // 10
基本使用:
reduceRight
方法对数组中的每个元素执行一个由您提供的reducer
函数(降序执行),将其结果汇总为单个返回值 mdn
和reduce
很类似,唯一不同的是reduceRight
从右往左遍历
const sum = [1, 2, 3, 4].reduce((prev, cur) => {
console.log(cur)
return prev + cur;
})
// 2 1
// 3 2
// 4 3
console.log(sum) // 10
const sum2 = [1, 2, 3, 4].reduceRight((prev, cur) => {
console.log(cur)
return prev + cur;
})
// 3 2
// 2 1
// 1 0
console.log(sum2) // 10
代码实现:
点击查看源码实现
Array.prototype.reduceRight2 = function (callback, initValue) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
let pre = initValue
const length = this.length
// 从最后一个元素开始遍历
let i = length - 1
// 如果没有传递初始值,则取最后一个作为初始值
if (typeof pre === 'undefined') {
pre = this[i]
i--
}
while (i >= 0) {
if (i in this) {
pre = callback(pre, this[ i ], i, this)
}
i--
}
return pre
}
测试:
const sum = [1, 2, 3, 4].reduceRight2((prev, cur) => {
console.log(cur)
return prev + cur;
})
// 3 2
// 2 1
// 1 0
console.log(sum) // 10
基本使用:
find 方法返回数组中满足测试函数的第一个元素的值。否则返回
undefined
, mdn
注意点:
find
方法对数组中的每一项元素执行一次 callback
函数,直至有一个 callback
返回 trueundefined
callback
函数会为数组中的每个索引调用即从 0 到 length - 1
,而不仅仅是那些被赋值的索引。(这个点是和前面几个函数不一样的地方)
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.find((it) => {
return it > 3
}, { name: '前端胖头鱼' })
console.log(index) // 4
代码实现:
Array.prototype.find2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
while (i < length) {
const value = this[ i ]
// 只要有一个元素符合callback回调函数的逻辑,就返回元素value
if (callback.call(thisCtx, value, i, this)) {
return value
}
i++
}
// 否则返回undefined
return undefined
}
测试:
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.find2(function (it, i, array) {
console.log(it, i, array, this)
return it > 3
}, { name: '前端胖头鱼' })
console.log(index) // 4
基本使用:
findIndex
方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。 mdnfindIndex
是返回索引而非值, 注意点也和find基本一样callback
函数返回true的值。length
为0,则findIndex
返回-1Array#some
)不同,在稀疏数组中,即使对于数组中不存在的条目的索引也会调用回调函数
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.findIndex((it, i, array) => {
return it > 2
})
console.log(index) // 3
代码实现:
点击查看源码实现
Array.prototype.findIndex2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
const length = this.length
let i = 0
while (i < length) {
// 符合callback逻辑的直接返回索引i
if (callback.call(thisCtx, this[ i ], i, this)) {
return i
}
i++
}
// 否则返回-1
return -1
}
测试:
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.findIndex2(function (it, i, array) {
console.log(it, i, array, this)
return it > 2
}, { name: '前端胖头鱼' })
console.log(index) // 3
基本使用:
indexOf
方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。 mdn
arr.indexOf(searchElement[, fromIndex])
注意点:
const array = [2, 5, 9]
console.log(array.indexOf(2)) // 0
console.log(array.indexOf(7)) // -1
console.log(array.indexOf(9, 2)) // 2
console.log(array.indexOf(2, -1)) // -1
console.log(array.indexOf(2, -3)) // 0
代码实现:
点击查看源码实现
有了上面的注意点和基本你使用,聪明的你肯定一眼就知道怎么写啦
Array.prototype.indexOf2 = function (targetEle, fromIndex) {
const length = this.length
fromIndex = +fromIndex || 0
// 数组为空或者从大于等于数组长度的地方开始检索,都直接是-1
if (length === 0 || fromIndex >= length) {
return -1
}
let i = Math.max(fromIndex >= 0 ? fromIndex : length - Math.abs(fromIndex), 0)
while (i < length) {
// 在数组内的元素并且和targetEle强等
if (i in this && targetEle === this[ i ]) {
return i
}
i++
}
return -1
}
测试:
const array = [2, 5, 9]
console.log(array.indexOf2(2)) // 0
console.log(array.indexOf2(7)) // -1
console.log(array.indexOf2(9, 2)) // 2
console.log(array.indexOf2(2, -1)) // -1
console.log(array.indexOf2(2, -3)) // 0
基本使用:
lastIndexOf
方法返回指定元素在数组中的最后一个的索引,如果不存在则返回 -1。 mdn
arr.lastIndexOf(searchElement[, fromIndex])
注意点:
arr.length - 1
位置开始逆向查找。fromIndex
大于或等于数组的长度,则整个数组会被查找。fromIndex
为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。fromIndex
值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
let array = [2, 5, 9, 2]
console.log(array.lastIndexOf(2)) // 3
console.log(array.lastIndexOf(7)) // -1
console.log(array.lastIndexOf(2, 3)) // 3
console.log(array.lastIndexOf(2, 2)) // 0
console.log(array.lastIndexOf(2, -2)) // 0
console.log(array.lastIndexOf(2, -1)) // 3
代码实现:
点击查看源码实现
Array.prototype.lastIndexOf2 = function (targetEle, fromIndex) {
const length = this.length
fromIndex = typeof fromIndex === 'undefined' ? length - 1 : fromIndex
// 数组为空,以及该值为负时且绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
if (length === 0 || fromIndex < 0 && Math.abs(fromIndex) >= length) {
return -1
}
let i
if (fromIndex >= 0) {
// 如果`fromIndex`大于或等于数组的长度,则整个数组会被查找。
// 也就是当大于数组length - 1时,会取length - 1
i = Math.min(fromIndex, length - 1)
} else {
i = length - Math.abs(fromIndex)
}
while (i >= 0) {
// 等于targetEle时返回索引
if (i in this && targetEle === this[ i ]) {
return i
}
// 逆向遍历
i--
}
// 没找到返回-1
return -1
}
测试:
let array = [2, 5, 9, 2] console.log(array.lastIndexOf2(2)) // 3 console.log(array.lastIndexOf2(7)) // -1 console.log(array.lastIndexOf2(2, 3)) // 3 console.log(array.lastIndexOf2(2, 2)) // 0 console.log(array.lastIndexOf2(2, -2)) // 0 console.log(array.lastIndexOf2(2, -1)) // 3
基本使用:
includes
方法用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回false
。mdn
arr.includes(valueToFind[, fromIndex])
注意点:
valueToFind
。array.length + fromIndex
的索引开始搜,[ ..., NaN ].includes(NaN
)为true
console.log([1, 2, 3].includes(2)) // true
console.log([1, 2, 3].includes(4)) // false
console.log([1, 2, 3].includes(3, 3)) // false
console.log([1, 2, 3].includes(3, -1)) // true
console.log([1, 2, NaN].includes(NaN)) // true
代码实现:
点击查看源码实现
Array.prototype.includes2 = function (targetEle, fromIndex) {
const length = this.length
fromIndex = +fromIndex || 0
// 数组为空或者从大于等于数组长度的地方开始检索,都直接是-1
if (length === 0 || fromIndex >= length) {
return false
}
let i = Math.max(fromIndex >= 0 ? fromIndex : length - Math.abs(fromIndex), 0)
while (i < length) {
const value = this[ i ]
// 注意NaN情况
if (targetEle === value || typeof targetEle === 'number' && typeof value === 'number' && isNaN(targetEle) && isNaN(value)) {
return true
}
i++
}
return false
}
测试:
console.log([1, 2, 3].includes2(2)) // true
console.log([1, 2, 3].includes2(4)) // false
console.log([1, 2, 3].includes2(3, 3)) // false
console.log([1, 2, 3].includes2(3, -1)) // true
console.log([1, 2, NaN].includes2(NaN)) // true
基本使用:
push
方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。mdn
const animals = ['pigs', 'Goats', 'sheep']
animals.push('cows')
console.log(animals, animals.length)
// ["pigs", "goats", "sheep", "cows"], 4
animals.push('chickens', 'cats', 'dogs')
console.log(animals, animals.length)
// ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"], 7
代码实现:
点击查看源码实现
Array.prototype.push2 = function (...pushEles) {
const pushEleLength = pushEles.length
const length = this.length
let i = 0
while (i < pushEleLength) {
this[ length + i ] = pushEles[ i ]
i++
}
return this.length
}
测试:
const animals = ['pigs', 'goats', 'sheep']
animals.push2('cows')
console.log(animals, animals.length)
// ["pigs", "goats", "sheep", "cows"], 4
animals.push2('chickens', 'cats', 'dogs')
console.log(animals, animals.length)
// ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"], 7
基本使用:
pop方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。mdn
let arr = [ 1, 2 ]
let arr2 = []
console.log(arr.pop(), arr) // 2 [1]
console.log(arr2.pop(), arr2) // undefined []
代码实现和使用一样简单,只要把数组的最后一个元素返回,并且让数组长度减1即可
代码实现:
点击查看源码实现
Array.prototype.pop2 = function () {
const length = this.length
// 空数组上pop,直接返回undefined
if (length === 0) {
return undefined
}
const delEle = this[ length - 1 ]
this.length = length - 1
return delEle
}
测试:
let arr = [ 1, 2 ]
let arr2 = []
console.log(arr.pop2(), arr) // 2 [1]
console.log(arr2.pop2(), arr2) // undefined []
基本使用:
unshift
方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组 ) 。
注意点:
例如:
let arr = [4,5,6]
// 一次性插入
arr.unshift(1,2,3)
console.log(arr) // [1, 2, 3, 4, 5, 6]
let arr2 = [4,5,6]
// 插入多次
arr2.unshift(1)
arr2.unshift(2)
arr2.unshift(3)
console.log(arr2); // [3, 2, 1, 4, 5, 6]
代码实现:
点击查看源码实现
Array.prototype.unshift2 = function (...unshiftEles) {
// 借助扩展符,将需要添加的元素以块的形式插入到数组前面
let newArray = [ ...unshiftEles, ...this ]
let length = newArray.length
let i = 0
if (unshiftEles.length === 0) {
return length
}
// 重新复制给数组
while (i < length) {
this[ i ] = newArray[ i ]
i++
}
return this.length
}
测试:
let arr = [4,5,6]
// 一次性插入
arr.unshift2(1,2,3)
console.log(arr) // [1, 2, 3, 4, 5, 6]
let arr2 = [4,5,6]
// 插入多次
arr2.unshift2(1)
arr2.unshift2(2)
arr2.unshift2(3)
console.log(arr2); // [3, 2, 1, 4, 5, 6]
基本使用:
shift 方法从数组中删除第一个元素,并返回该元素的值。 mdn
let arr = [ 1, 2 ]
console.log(arr.shift(), arr) // 1 [2]
console.log(arr.shift(), arr) // 2 []
代码实现:
点击查看源码实现
Array.prototype.shift2 = function () {
const length = this.length
const delValue = this[ 0 ]
let i = 1
while (i < length) {
// 从第一个元素开始,后面的元素都往前移动一位
this[ i - 1 ] = this[ i ]
i++
}
// 设置好数组的长度
this.length = length - 1
// 返回删除的值
return delValue
}
测试:
let arr = [ 1, 2 ]
console.log(arr.shift2(), arr) // 1 [2]
console.log(arr.shift2(), arr) // 2 []
基本使用:
reverse
方法将数组中元素的位置颠倒,并返回该数组。即数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。mdn
``` javascript
const arr = [1, 2, 3]
console.log(arr) // [1, 2, 3]
arr.reverse()
console.log(arr) // [3, 2, 1]
代码实现:
点击查看源码实现
Array.prototype.reverse2 = function () {
// 设置双指针,往中间靠拢
let i = 0
let j = this.length - 1
while (i < j) {
// 第一个和最后一个,第二个和倒数第二个进行位置调换
[ this[ i ], this[ j ] ] = [ this[ j ], this[ i ] ]
i++
j--
}
return this
}
测试:
const arr = [1, 2, 3]
console.log(arr) // [1, 2, 3]
arr.reverse2()
console.log(arr) // [3, 2, 1]
基本使用:
fill
方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。mdn
const array1 = [1, 2, 3, 4];
console.log(array1.fill(0, 2, 4)) // [1, 2, 0, 0]
console.log(array1.fill(5, 1)) // [1, 5, 5, 5]
console.log(array1.fill(6)) // [6, 6, 6, 6]
代码实现:
点击查看源码实现
Array.prototype.fill2 = function (value, start, end) {
const length = this.length
start = start >> 0
// end没填的话,默认是length,否则取填写的
end = typeof end === 'undefined' ? length : end >> 0
// start最小取0,最大取length
start = start >= 0 ? Math.min(start, length) : Math.max(start + length, 0)
// end最小取0,最大取length
end = end >= 0 ? Math.min(end, length) : Math.max(end + length, 0)
// 填充指定范围的索引为value
while (start < end) {
this[ start ] = value
start++
}
// 返回被修改的数组
return this
}
测试:
const array1 = [1, 2, 3, 4];
console.log(array1.fill2(0, 2, 4)) // [1, 2, 0, 0]
console.log(array1.fill2(5, 1)) // [1, 5, 5, 5]
console.log(array1.fill2(6)) // [6, 6, 6, 6]
连接、拼接
基本使用:
concat
方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组 mdn
let num1 = [[1]]
let num2 = [2, [3]]
let num3=[5,[6]]
let nums = num1.concat(num2) // [[1], 2, [3]]
let nums2 = num1.concat(4, num3) // [[1], 4, 5,[6]]
代码实现:
点击查看源码实现
Array.prototype.concat2 = function (...concatEles) {
const length = concatEles.length
// 数组本身展开一层
let newArray = [ ...this ]
let i = 0
while (i < length) {
const value = concatEles[ i ]
// 对数组元素展开一层
Array.isArray(value) ? newArray.push(...value) : newArray.push(value)
i++
}
return newArray
}
测试:
let num1 = [[1]]
let num2 = [2, [3]]
let num3=[5,[6]]
let nums = num1.concat2(num2) // [[1], 2, [3]]
let nums2 = num1.concat2(4, num3) // [[1], 4, 5,[6]]
基本使用:
join
方法将一个数组的所有元素通过字符标识连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
const elements = ['Fire', 'air', 'Water']
const elements2 = ['Fire']
console.log(elements.join()) // Fire,Air,Water
console.log(elements.join('')) // FireAirWater
console.log(elements.join('-')) // Fire-Air-Water
console.log(elements2.join('-')) // Fire
代码实现:
点击查看源码实现
Array.prototype.join2 = function (fORMat = ',') {
const length = this.length
// 保存最后一个元素,因为他不参与format连接
let lastEle = this[ length - 1 ]
let string = ''
if (length === 0) {
return string
}
for (i = 0; i < length - 1; i++) {
string += this[ i ] + format
}
return string + lastEle
}
测试:
const elements = ['Fire', 'Air', 'Water']
const elements2 = ['Fire']
console.log(elements.join2()) // Fire,Air,Water
console.log(elements.join2('')) // FireAirWater
console.log(elements.join2('-')) // Fire-Air-Water
console.log(elements2.join2('-')) // Fire
基本使用:
Array.isArray()
用于确定传递的值是否是一个 Array。
Array.isArray([1, 2, 3]) // true
Array.isArray({foo: 123}) // false
Array.isArray("foobar") // false
Array.isArray(undefined) // false
代码实现:
点击查看源码实现
这个非常简单,只需要一句话就可以
Array.isArray2 = function (ele) {
return Object.prototype.toString.call(ele) === '[object Array]';
}
测试:
Array.isArray2([1, 2, 3]) // true
Array.isArray2({foo: 123}) // false
Array.isArray2("foobar") // false
Array.isArray2(undefined) // false
基本使用:
Array.of
方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
注意点:
Array.of()
和 Array 构造函数之间的区别在于处理整数参数:Array.of(7)
创建一个具有单个元素 7 的数组,而 Array(7) 创建一个长度为7的空数组(注意: 这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
代码实现:
击查看源码实现
实现思路就是把你穿进去的值,挨个赋值到当前数组即可
Array.of2 = function (...eles) {
const length = eles.length
let i = 0
let newArray = []
while (i < length) {
newArray[ i ] = eles[ i ]
i++
}
return newArray
}
测试:
Array.of2(7); // [7]
Array.of2(1, 2, 3); // [1, 2, 3]
基本使用:
flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。 mdn
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat()) // [0, 1, 2, 3, 4] 默认会平铺展开一层
const arr2 = [0, 1, 2, [[[3, 4]]]]
console.log(arr2.flat(2)) // [0, 1, 2, [3, 4]] 指定展开两层
代码实现:
点击查看源码实现
Array.prototype.flat2 = function (depth = 1) {
const result = []
const flat = (arr, depth) => {
for (let item of arr) {
// 当层数还未全部展开的时候,进行递归处理
if (Array.isArray(item) && depth > 0) {
flat(item, depth - 1)
} else {
// 去除空元素,添加非undefined元素
item !== void 0 && result.push(item)
}
}
}
flat(this, depth)
return result
}
测试:
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat2()) // [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]]
console.log(arr2.flat2(2)) // [0, 1, 2, [3, 4]]
基本使用:
flatMap
方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同。 mdn
let arr = [1, 2, 3, 4]
arr.flatMap(x => [x * 2]) // [2, 4, 6, 8]
代码实现:
点击查看源码实现
Array.prototype.flatMap2 = function (callback, thisCtx) {
if (typeof callback !== 'function') {
throw `${callback} is not a function`
}
// map和flat具体实现可以看map.js和flat.js
return this.map(function (it, i, array) {
return callback.call(thisCtx, it, i, array)
}).flat(1)
}
测试:
let arr = [1, 2, 3, 4]
arr.flatMap2(x => [x * 2]) // [2, 4, 6, 8]
结尾:
到此这篇关于徒手实现关于JavaScript的24+数组方法的文章就介绍到这了,更多相关实现关于JavaScript的24+数组方法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
国庆将至,祝大家节日快乐,浪浪浪七天乐。
--结束END--
本文标题: 徒手实现关于JavaScript的24+数组方法
本文链接: https://lsjlt.com/news/137032.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0