乐趣区

关于javascript:JavaScript重写数组的concat方法

1. 先看文档:


浏览文档,从中演绎要害信息:

1. 用于连贯两个或多个数组
2. 返回一个新数组
3. 参数能够是任意多个具体的值或数组对象
4. 如果传入数组则增加的是数组的每个元素

所以依照这个思路,咱们大略能猜到它是如何实现的:

1. 首先有一个期待拼接的数组对象,
2. 而后能够将要拼接的具体的值或数组对象传入,
3. 如果传入的是具体的值则间接推到期待拼接的数组;如果传入的是数组则遍历该数组将其每一个元素都推到期待拼接的数组中,
4. 如果传入的是两个及以上的值或数组则反复第三步。

举例:

let arr = [1, 2, 3]

// 传入一个具体的值
console.log(arr.concat(4)) // [1, 2, 3, 4]
// 传入一个数组对象
console.log(arr.concat([4, 5])) // [1, 2, 3, 4, 5]
// 传入两个及以上具体的值
console.log(arr.concat(4, 5, 6)) // [1, 2, 3, 4, 5, 6]
// 传入两个及以上数组对象
console.log(arr.concat([4, 5], [6, 7])) // [1, 2, 3, 4, 5, 6, 7, 8, 9]

2. 开始实操:

第一步,拼接一个或多个具体的值,并返回新数组:

let arr = [1, 2, 3]
/**
 * @description: 重写数组 concat()
 * @return {object array} waitingArr - 拼接后的数组对象
 */
Array.prototype.myConcat = function () {
     /**
     * 被返回的数组
     * 1. 不能简略的让 waitingArr = this,会批改原数组
     * 2. 将 this 中的每一个元素推入新数组
     */
     let waitingArr = this.filter(item => new Array(item))
     /**
     * 解决传入的参数:* 1.arguments 是类数组须要先转换成数组
     * 2. 遍历转换后的数组并将每一个元素推入到原来的数组
     */
     Array.prototype.slice.call(arguments).forEach(ele => {waitingArr.push(ele)
     }) 
     // 返回拼接后的新数组
     return waitingArr
    }
console.log(arr.myConcat(4), arr) // [1, 2, 3, 4] [1, 2, 3]
console.log(arr.myConcat(4, 5, 6), arr) // [1, 2, 3, 4, 5, 6] [1, 2, 3]

第二步,拼接一个或多个具体的值或数组对象,并返回新数组:

Array.prototype.myConcat = function () {let waitingArr = this.filter(item => new Array(item))
     /**
     * 解决传入的参数:* 3. 判断参数中是否蕴含数组,如果蕴含则拼接其每一个元素
     */
     Array.prototype.slice.call(arguments).forEach(ele => {if (Array.isArray(ele)) {
             ele.forEach(item => {waitingArr.push(item)
             }) 
         } else {waitingArr.push(ele)
         }  
     })
     return waitingArr
}
console.log(arr.myConcat([4, 5]), arr) // [1,2,3,4,5] [1,2,3]
console.log(arr.myConcat([4, 5], [6, 7]), arr) // [1,2,3,4,5,6,7] [1,2,3]
console.log(arr.myConcat([4, 5], [6, 7], 123, 333), arr) // [1,2,3,4,5,6,7,123,333] [1,2,3]

代码整顿:

/**
 * @description: 重写数组 concat()
 * @return {object array} waitingArr - 拼接后的数组对象
 */
Array.prototype.myConcat = function () {let waitingArr = this.filter(item => new Array(item))
     Array.prototype.slice.call(arguments).forEach(ele => {Array.isArray(ele) ? ele.filter(item => waitingArr.push(item)) : waitingArr.push(ele)
     }) 
     return waitingArr
}

好了重写完结,然而在重写的过程中发现了一些货色很有意思。本来的 concat()直观体现是咱们在拼接具体的值得时候如同只是把这些值一个一个推动去,然而在原理上它还是在解决数组。因为 arguments 对象自身是一个类数组。

所以本来的 arr.concat(4, 5, 6)这种模式,本质上是在解决一维数组;而 arr.concat([4,5])这种模式,本质上是在解决二维数组。

那么持续向下思考,如果咱们拼接的是一个或多个多维数组,又该怎么去解决呢?很显然依照下面的这种形式。。。细思极恐,那必定是要向下解决很多层的。

因为我也没应用 concat 拼接过多维数组,所以先来看看本来的后果:

let arr = [1, 2, 3]
console.log(arr.concat([4, [5, 6, [7, 8, [9, 10, ['哈哈', '哈哈哈']]]]]))
// 后果:[1, 2, 3, 4, [ 5, 6, [ 7, 8, [Array] ] ] ]

本来我认为它会最终返回一维数组,万万没想到啊,哈哈哈哈哈哈哈!!!!拼接到很多层的时候编辑器更是不往下解决了,就间接 [Array] 了,哈哈哈哈哈哈哈!!!!。

而后再拿到浏览器看看:

所以失去一个论断,咱们常常应用的 concat 最多只能拼接一维数组。所以下面封装好的办法就是正确的。

3. 总结

其实偶然回顾一下根底,尝试着重写根底办法,真的可能带来很多播种。可能对一些底层的货色更加相熟,而相熟这些货色的收益就是写出更完满更高效的办法。也可能在面对不同的需要时,最疾速的做出解决方案。也能在将来的工作中独挡一面,一直的造轮子,造好轮子,进步本人甚至是整个团队的工作效率。

前面会做一个 concat 办法的延长,” 实现多维数组拼接成一维数组 ”。兴许! 没什么卵用,但但凡都有个万一。而且多钻研钻研原理对技术的晋升是有极大帮忙的。


Keep foolish, keep hungry.

退出移动版