Preface
" public account. Maybe you have never met before, but it is very likely that you are too late to meet.
array is the most frequently used data structure in our daily work. It can help us solve many problems. It also contains nearly 33 methods. A brain map is classified as follows. You who are proficient in using arrays , Do you want to know their internal implementation principles?
This article will explore the internal implementation of the 24+ native array methods with you. I believe you will have a different harvest after reading it.
Traversal class
1. forEach
Basic use
forEach
are so many traversal functions that are used daily, you must be familiar enough that you can no longer be familiar with it! Here we focus on some of the more important and easily overlooked points. mdn
- This method executes the given function once for each element of the array, and the return value is
undefiend
. callback
function once for each item in the with a valid value of in ascending order, and uninitialized items will be skipped (for example, on a sparse array).- If the existing value is changed, the value passed to
callback
the value atforEach()
traverses to them. - Deleted items will not be traversed to
give a small example
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)
})
/*
1
2
3
4-4
5
*/
Code
Click to view the source code to achieve
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++
}
}
Using the example just now, the output after the change is the same
Test a handful
// 测试
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)
})
/*
1
2
3
4-4
5
*/
2. map
Basic use
map
method creates a new array, and the result is that each element in the array is the return value after calling the provided function once. mdn
Note
callback
function will only be called on indexes that have a value- Indexes that have never been assigned or
delete
will not be called.
// 注意索引为2的位置没有赋值
let arr = [ 1, 2, ,4, 5 ]
// 删除索引3
delete arr[3]
console.log(arr.map((it) => it * it))
// [ 1, 4, 25 ]
Code
Click to view the source code to achieve
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
}
Test a handful
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)
3. every
Basic use
every
method tests whether all elements in an array can pass the test of a specified function. It returns a boolean value. mdn
note
- If an empty array is received, this method will return
true
in all cases. callback
will only be called for those indexes that have already been assigned- Will not be called for indexes that have been deleted or have never been assigned
// 举例
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
Code
Click to view the source code to achieve
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
}
Test a handful
still use examples to test
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
4. some
Basic use
some
method tests whether at least one element in the array has passed the provided function test. It returns a Boolean value. mdn
Note
callback
will only be called on indexes that "have a value", and will not be called on indexes that have been deleted or have never been assigned.
for example
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
Code
Click to view the source code to achieve
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
}
Test a handful
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
5. filter
Basic use
filter
method creates a new array that contains all the elements that pass the provided function test. mdn
Note
filter
is called once for each element in the arraycallback
function, and using all suchcallback
return true or equivalent to the true value elements to create a new array.callback
will only be called on indexes that have been assigned, and will not be called on indexes that have been deleted or have never been assigned.- Those elements that fail the
callback
test will be skipped and will not be included in the new array.
// 索引为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 ]
Code
Click to view the source code to achieve
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
}
test
// 索引为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 ]
6. reduce
Basic use
reduce
reducer function (executed in ascending order) provided by you for each element in the array, and aggregates the results into a single return value mdn
This function is a bit more complicated, let's use an example to see how it is used.
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 (退出)
Code
Click to view the source code to achieve
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
}
Test a handful
const sum = [1, 2, 3, 4].reduce2((prev, cur) => {
return prev + cur;
})
console.log(sum) // 10
7. reduceRight
Basic use
reduceRight
reducer function (executed in descending order) provided by you for each element in the array, and aggregates the results into a single return value mdn
Similar to reduce, the only difference is that reduceRight
traverses from right to left
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
Code
Click to view the source code to achieve
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
}
Test a handful
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
Lookup class
8. find
Basic use
find
method returns the value of the first element in the array that satisfies the test function. Otherwise returnundefined
, mdn
be careful
find
callback
function once for each element in the array until a callback returnstrue
- When such an element is found, the method will immediately return the value of this element, otherwise it will return
undefined
callback
function will be called for each index in the array, from0
tolength - 1
, not just those indexes that are assigned.(This point is different from the previous functions)
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.find((it) => {
return it > 3
}, { name: '前端胖头鱼' })
console.log(index) // 4
Code
Click to view the source code to achieve
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
}
Test a handful
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
9. findIndex
Basic use
findIndex
index of the first element in the array that satisfies the provided test function. If no corresponding element is found, -1 is returned. mdn
The difference from the find function is that findIndex returns the instead of the value . Note that it is basically the same as find
findIndex
callback
function once for each array index0 ~ length-1
(including) in the array until it finds acallback
function returns true.- If such an element is found,
findIndex
will immediately return the index of the element. If the callback never returns a true value, or thelength
of the array is 0, thenfindIndex
returns -1 - Unlike some other array methods (such as Array#some), in a sparse array, the callback function is called even for the index of an entry that does not exist in the array
let arr = [ 0, 1, 2, 3, 4,, 5 ]
let index = arr.findIndex((it, i, array) => {
return it > 2
})
console.log(index) // 3
Code
Click to view the source code to achieve
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
}
Test a handful
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
10. indexOf
Basic use
indexOf
method returns the first index at which a given element can be found in the array, or -1 if it does not exist. mdn
arr.indexOf(searchElement[, fromIndex])
Note
- If the index value at the beginning of the search is greater than or equal to the length of the array, it means that it will not be searched in the array and returns -1
- If the index value provided in the parameter is a negative value , it will be used as an offset at the end of the array, that is, -1 means searching from the last element, -2 means searching from the penultimate element, and so on
- If the index value provided in the parameter is a negative value, the search order is not changed, and the search order is still to query the array from front to back
- If the offset index value is still less than 0, the entire array will be queried. Its default value is 0.
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
Code
Click to view the source code to achieve
With the above points of attention and basic use, you will know how to write at a glance.
Array.prototype.indexOf2 = function (targetEle, fromIndex) {
const length = this.length
fromIndex = +fromIndex || 0
// 数组为空或者从大于等于数组长度的地方开始检索,都直接是-1
if (length === 0 || fromIndex >= length) {
return -1
}
/*
1. 从fromIndex开始搜索元素
2. fromIndex大于0时候直接取即可
3. 小于0先用长度减去fromIndex的绝对值,如果还是小于0,就直接取0即可
*/
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
}
Test a handful
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
11. lastIndexOf
Basic use
lastIndexOf
method returns the last index of the specified element in the array, or -1 if it does not exist. mdn
arr.lastIndexOf(searchElement[, fromIndex])
Note
- Start the reverse search from the
arr.length - 1
- If
fromIndex
greater than or equal to the length of the array, the entire array will be searched. - If
fromIndex
is negative, treat it as an offset from the end of the array forward. Even if the value is negative, the array will still be searched from back to front. - If the
fromIndex
is negative and its absolute value is greater than the length of the array, the method returns -1, that is, the array will not be searched.
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
Code
Click to view the source code to achieve
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
}
Test a handful
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
12. includes
Basic use
includes
method is used to determine whether an array contains a specified value, if it contains, it returns true, otherwise it returns false. mdn
arr.includes(valueToFind[, fromIndex])
Note
- From
fromIndex
index FindvalueToFind
. - If it is a negative value, start searching from the index of
array.length + fromIndex
- If there is NaN in the array,
[..., NaN ].includes(NaN) is 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
Code
Click to view the source code to achieve
Array.prototype.includes2 = function (targetEle, fromIndex) {
const length = this.length
fromIndex = +fromIndex || 0
// 数组为空或者从大于等于数组长度的地方开始检索,都直接是-1
if (length === 0 || fromIndex >= length) {
return false
}
/*
1. 从fromIndex开始搜索元素
2. fromIndex大于0时候直接取即可
3. 小于0先用长度减去fromIndex的绝对值,如果还是小于0,就直接取0即可
*/
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
}
Test a handful
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
Additions, deletions and modifications
13. push
Basic use
push
method adds one or more elements to the end of the array and returns the new length of the array. 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
Code
Click to view the source code to achieve
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
}
Test a handful
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
14. pop
Basic use
pop
method deletes the last element from the array and returns the value of that element. This method changes the length of the array. mdn
let arr = [ 1, 2 ]
let arr2 = []
console.log(arr.pop(), arr) // 2 [1]
console.log(arr2.pop(), arr2) // undefined []
The code implementation is as simple as the use, just return the last element of the array and reduce the length of the array by 1.
Code
Click to view the source code to achieve
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
}
Test a handful
let arr = [ 1, 2 ]
let arr2 = []
console.log(arr.pop2(), arr) // 2 [1]
console.log(arr2.pop2(), arr2) // undefined []
15. unshift
Basic use
unshift
method of one or more elements to the array beginning , and returns the array new length (the method modifies the original array ) .
Note
- If multiple parameters are passed in, they will be inserted at the beginning of the object in the form of blocks, and their order is the same as the order when passed as parameters.
unshift
once with multiple parametersunshift
multiple times with one parameter (for example, loop call), they will get different results. E.g:
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]
Code
Click to view the source code to achieve
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
}
Test a handful
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]
16. shift
Basic use
shift
method removes from the array first element, and returns the value of the element. mdn
let arr = [ 1, 2 ]
console.log(arr.shift(), arr) // 1 [2]
console.log(arr.shift(), arr) // 2 []
Code
Click to view the source code to achieve
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
}
Test a handful
let arr = [ 1, 2 ]
console.log(arr.shift2(), arr) // 1 [2]
console.log(arr.shift2(), arr) // 2 []
17. reverse
Basic use
reverse
method reverses the position of the elements in the array and returns the array. That is, the first element of the array will become the last, and the last element of the array will become the first. mdn
const arr = [1, 2, 3]
console.log(arr) // [1, 2, 3]
arr.reverse()
console.log(arr) // [3, 2, 1]
Code
Click to view the source code to achieve
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
}
Test a handful
const arr = [1, 2, 3]
console.log(arr) // [1, 2, 3]
arr.reverse2()
console.log(arr) // [3, 2, 1]
18. fill
Basic use
fill
method fills all elements in an array from the start index to the end index with a fixed value. Does not include the termination index. 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]
Code
Click to view the source code to achieve
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
}
Test a handful
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]
Connection, splicing
19. concat
Basic use
concat
method is used to merge two or more arrays. This method does not change the existing array, but returns a new array 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]]
Code
Click to view the source code to achieve
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
}
Test a handful
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]]
20. join
Basic use
join
method concatenates all the elements of an arraycharacter identifier and returns this string. If the array has only one item, then that item will be returned without using the separator.
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
Code
Click to view the source code to achieve
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
}
Test a handful
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
Static method
21. Array.isArray
Basic use
Array.isArray() used to determine whether the passed value is a Array
.
Array.isArray([1, 2, 3]) // true
Array.isArray({foo: 123}) // false
Array.isArray("foobar") // false
Array.isArray(undefined) // false
Code
Click to view the source code to achieve
This is very simple, it only takes one sentence
Array.isArray2 = function (ele) {
return Object.prototype.toString.call(ele) === '[object Array]';
}
Test a handful
Array.isArray2([1, 2, 3]) // true
Array.isArray2({foo: 123}) // false
Array.isArray2("foobar") // false
Array.isArray2(undefined) // false
22. Array.of
Basic use
Array.of
method creates a new array instance with a variable number of parameters, regardless of the number or type of parameters.
Note
Array.of()
and Array
constructors is the handling of integer parameters:
Array.of(7)
creates an array with a single element 7 , and Array(7)
creates an empty array with a length of 7 ( Note: This refers to an array with 7 empty positions ( undefined
Array)
Array.of(7); // [7]
Array.of(1, 2, 3); // [1, 2, 3]
Array(7); // [ , , , , , , ]
Array(1, 2, 3); // [1, 2, 3]
Code
Click to view the source code to achieve
The realization idea is to assign the values you pass in to the current array one by one.
Array.of2 = function (...eles) {
const length = eles.length
let i = 0
let newArray = []
while (i < length) {
newArray[ i ] = eles[ i ]
i++
}
return newArray
}
Test a handful
Array.of2(7); // [7]
Array.of2(1, 2, 3); // [1, 2, 3]
Flat class
23. flat
Basic use
flat()
method will recursively traverse the array according to a specified depth, and merge all the elements with the elements in the traversed sub-array into a new array and return. 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]] 指定展开两层
Code
Click to view the source code to achieve
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
}
Test a handful
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]]
24. flatMap
Basic use
flatMap
method first uses the mapping function to map each element, and then compresses the result into a new array. It is almost the same as map flat depth value of 1. mdn
let arr = [1, 2, 3, 4]
arr.flatMap(x => [x * 2]) // [2, 4, 6, 8]
Code
Click to view the source code to achieve
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)
}
test
let arr = [1, 2, 3, 4]
arr.flatMap2(x => [x * 2]) // [2, 4, 6, 8]
end
National Day is approaching, I wish you all a happy holiday and seven days of joy.
The article may contain problems or insufficient implementation. You are welcome to point out in the comment area, and you must make corrections without stopping. Thanks.
Due to the length of the article, there are still many array methods that have not been written in the article. If they are of some use to you, we will
splice
follow-up on the original implementation of the remaining functions such as 0617205b0da9ba,keys
,values
Good night everyone 🌹
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。