JS处理数组方法重写

168 阅读1分钟

0.foreach

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_foreach = function (callback) {
    for (let i = 0; i < this.length; i++) {
        callback(this[i], i, this)
    }
}
arr.my_foreach(item => console.log(`这是${item}`))
// 这是10
// 这是20
// 这是30
// 这是40
// 这是50

注意ES6新增的这几个方法,只有foreach不需要再回调函数中写return。

且foreach是可以改变数组本身的,要借助回调函数的第三个参数。

arr.forEach((item, index, self) => {
    self[index] = item + 1
})
console.log(arr);
// [ 11, 21, 31, 41, 51 ]

1.filter

const arr = [10, 20, 30, 40, 50]

Array.prototype.my_filter = function (callback) {
    const res = [];
    for (let i = 0; i < this.length; i++) {
        callback(this[i], i, this) && res.push(this[i])
    }
    return res
}

const arr_filter = arr.my_filter(item => { return item > 10 })
console.log(arr_filter);//[ 20, 30, 40, 50 ]

注意:当调用filter时,如果回调函数不写return,则返回空数组。

2.map

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_map = function (callback) {
    const res = []
    for (let i = 0; i < this.length; i++) {
        res.push(callback(this[i], i, this))
    }
    return res
}
const arr_map = arr.my_map(item => { return item * 10 })
console.log(arr_map);//[ 100, 200, 300, 400, 500 ]

注意,若调用map方法时,回调函数里不写return,则返回数组长度个undefined。

3.every

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_every = function (callback) {
    let flag = true
    for (let i = 0; i < this.length; i++) {
        flag = callback(this[i], i, this)
        if (!flag) break
    }
    return flag
}
const arr_every = arr.my_every(item => { return item > 9 })
console.log(arr_every);// true

注意,调用every方法的回调函数时,不写return,返回undefined

4.some

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_some=function(callback){
    let flag=false
    for(let i=0;i<this.length;i++){
        flag=callback(this[i],i,this)
        if(flag) break
    }
    return flag
}
const arr_mysome=arr.my_some(item=>{return item>50})
console.log(arr_mysome)// false

注意,调用some方法的回调函数时,不写return,返回undefined

5.find

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_find=function(callback){
    for(let i=0;i<this.length;i++){
        if(callback(this[i],i,this))return this[i]
    } 
    return undefined
}
const arr_find=arr.my_find(item=>{return item===30})
console.log(arr_find);// 30

find方法是找到了返回当前项的值,找不到返回undefined

6.findIndex

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_findIndex=function(callback){
    for(let i=0;i<this.length;i++){
        if(callback(this[i],i,this)) return i
    }
    return -1
}
const arr_findIndex=arr.my_findIndex(item=>{return item===30})
console.log(arr_findIndex);// 2

findIndex找到了返回当前项的索引,找不到返回“-1”

7.fill

fill方法不常用,先回顾一下用法

const arr = [10, 20, 30, 40, 50]

// 如果fill里面只写要替换的值,则默认全部替换原数组
const new_arr=arr.fill('aa')
console.log(new_arr);// [ 'aa', 'aa', 'aa', 'aa', 'aa' ]

// fill是可以修改原数组的
console.log(arr); // [ 'aa', 'aa', 'aa', 'aa', 'aa' ]

// 第二个参数是要被替换的起始项的索引,第三个是要终止替换项的索引(当前索引项不会被替换)
const new_arr2=arr.fill('bb',1,3)
console.log(new_arr2);// [ 'aa', 'bb', 'bb', 'aa', 'aa' ]

fill方法重写

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_fill=function(value,startVal=0,endVal){
    endVal=endVal||this.length
    for(let i=startVal;i<endVal;i++){
        this[i]=value
    }
    return this
}
console.log(arr.my_fill('$&',1,3));// [ 10, '$&', '$&', 40, 50 ]

8.includes

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_includes=function(value){
    for(let i=0;i<this.length;i++){
        if(this[i]===value) return true
    }
    return false
}
console.log(arr.my_includes(30));// true
console.log(arr.my_includes(66));// false

包含返回true,不包含返回false。逻辑较为简单。

9.join

这个方法比较存在时间比较长,应该是ES5之前的方法,重写时可以使用三元来简化代码

const arr = [10, 20, 30, 40, 50]
Array.prototype.my_join=function(character=','){
    let str=''
    for(let i=0;i<this.length;i++){
        str= i==0?`${this[i]}`:`${str}${character}${this[i]}`
    }
    return str
}
console.log(arr.my_join());// 10,20,30,40,50
console.log(arr.my_join('#'));// 10#20#30#40#50

10.flat

flat用来扁平化数组,但是原生的flat只可以扁平化处里最外层的数组,无法达到深度处理的效果,如下所示:

const arr = [[10, [20, 30], 40, 50],70,80]
console.log(arr.flat());// [ 10, [ 20, 30 ], 40, 50, 70, 80 ]
console.log(arr.flat().flat());// [ 10, 20, 30, 40, 50, 70, 80 ]

所以,更新一下原flat,使得一次调用,就可以彻底扁平化处理数组。

const arr = [[10, [20, 30], 40, 50],70,80]
Array.prototype.my_flat=function(){
    let arr=this
    let flag=arr.some(item=>Array.isArray(item))
    while (flag) {
        arr=[].concat(...arr)
        flag=arr.some(item=>Array.isArray(item))
    }
    return arr
}
console.log(arr.my_flat());
// [ 10, 20, 30, 40, 50, 70, 80 ]