侧边栏壁纸
博主头像
woku博主等级

成功的路上并不拥挤

  • 累计撰写 50 篇文章
  • 累计创建 13 个标签
  • 累计收到 3 条评论

find/findIndex

woku
2021-11-20 / 0 评论 / 0 点赞 / 56 阅读 / 3,179 字

ES6版本中出现,Array.protorype上的一个内置方法

基本使用

    const arr = [1, 2, 3, 4, 5]
    const r = arr.find(x => x > 3)
    console.log(r)  // 第一个满足条件的是元素4,因此返回4

返回第一个符合条件的数组元素

    const arr = [1, 2, 3, 4, 5]
    const r = arr.find(x => x > 5)
    console.log(r)

如果没有一个数组元素满足,则返回undefined

数组元素是引用值

    const arr = [{
        id: 1
    }, {
        id: 2
    }, {
        id: 3
    }]
    const r = arr.find(x => x.id > 1)
    console.log(r)
    console.log(r === arr[1])

返回的元素和数组对应下标的元素是同一个引用

参数

第一个:回调函数

回调函数的参数:

回调函数(当前遍历元素,当前遍历元素的下标,当前数组)

    const arr = [{
        id: 1
    }, {
        id: 2
    }, {
        id: 3
    }]
    const r = arr.find(function(item, index, arr) {
        console.log(item, index, arr)
    })

img

第二个:更改回调函数中内部this指向

  • 不存在第二个参数,回调函数中的this在非严格模式下指向window, 在严格模式下指向undefined

        const arr = [{
            id: 1
        }, {
            id: 2
        }, {
            id: 3
        }]
        const r = arr.find(function(x) {
            console.log(this) // window
        })
    
  • 存在第二个参数,回调函数中的this指向第二个参数

        const arr = [{
            id: 1
        }, {
            id: 2
        }, {
            id: 3
        }]
        const r = arr.find(function(x) {
            console.log(this)  // {'a':1}
        }, {
            'a': 1
        })
    

改变this指向使用场景:

不用去外部拿引用,直接在函数内部用this接收

    var obj = {}
    var arr = [1, 2, 3, 4, 5]
        // const r = arr.find((item, index) => {
        //     if (item > 3) {
        //         obj[index] = item
        //     }
        //     return item > 3
        // })
    const r = arr.find(function(item, index) {
        if (item > 3) {
            this[index] = item
        }
        return item > 3
    }, obj)
    console.log(r)
    console.log(obj)

如果回调函数使用箭头函数是改变不了this指向的,箭头函数本身是起到稳定this指向的

固定索引范围

  • 使用find方法是不会更改数组的

        const arr = [1, , 3, , 5, , 7]
        arr.find(function(item, index) {
            item = item + 1
        })
        console.log(arr) // [1, , 3, , 5, , 7]
    
  • find方法固定最初的索引范围

        const arr = [1,  ,3, , 5, , 7]
        arr.find(function(item, index) {
            arr.push(6)
            console.log(item)
        })
        console.log(arr)
    

    arr在find的时候就知道了索引范围是0-7,在遍历的时候,对arr进行push操作后,不会重新执行回调函数。也就是最后是循环7次,每次循环都往数组push了6,但回调函数只执行7次。

    splice删除:

        const arr = [1, , 3, , 5, , 7]
        arr.find(function(item, index) {
            if (index == 1) {
                arr.splice(1, 1) 
            }
            console.log(item)
        })
        console.log(arr)
    

    使用splice删除了对应元素,该项位置不保留,因为固定了最初的索引范围(必须循环7次),在数组的最后补上undefined

    实际数组被删除了下标为1的项

    delete删除:

        const arr = [1, , 3, , 5, , 7]
        arr.find(function(item, index) {
            if (index == 1) {
                delete arr[2]
            }
            console.log(item)
        })
        console.log(arr)
    

    通过delete删除,删除对应元素,并在当前位置填入undefined

    实际数组中对应下标变成空隙

    pop删除:

        const arr = [1, , 3, , 5, , 7]
        arr.find(function(item, index) {
            if (index == 1) {
                arr.pop()
            }
            console.log(item)
        })
        console.log(arr)
    

    通过pop删除,删除对应元素,并在当前位置填入undefined

    实际数组被删除了最后一项

稀疏数组

什么是稀疏数组:数组元素和数组元素之间有空隙

eg:[1,,3,,5]

使用find方法遍历不会过滤掉空隙元素

    var arr = Array(5)
    arr[0] = 1
    arr[2] = 3
    arr[4] = 5
    console.log(arr)
    arr.find(function(item) {
        console.log('done')   // 打印5次'done'
    })

使用其他的ES5数组扩展方法,比如forEach、map、filter、reduce、reduceRight、some、every都会过滤掉空隙元素

由此可以看出:find的遍历效率是低于ES5数组扩展方法

findIndex

findIndex和find类似

findIndex 返回第一个满足条件的数组元素对应的下标

如果都不满足,返回-1

其他知识点和find一样

polyfill

  • find

      Array.prototype.myFind = function(cb) {
            if (this === null || this === undefined) {
                throw new Error('this is null or undefined')
            }
            if (typeof cb !== 'function') {
                throw new Error('callback must a function type')
            }
            var obj = Object(this),
                len = obj.length >>> 0,
                arg2 = arguments[1],
                step = 0
            while (step < len) {
                var value = obj[step]
                if (cb.call(arg2, value, step, obj)) {
                    return value
                }
                step++
            }
            return undefined
        }
        var arr = [1, 2, 3]
        var r = arr.myFind(function(item) {
            return item > 1
        })
        console.log(r)
    
  • findIndex

    Array.prototype.myFindIndex = function(cb) {
        if (this === null || this === undefined) {
            throw new Error('this is null or undefined')
        }
        if (typeof cb !== 'function') {
            throw new Error('callback must a function type')
        }
        var obj = Object(this),
            len = obj.length >>> 0,
            arg2 = arguments[1],
            step = 0
        while (step < len) {
            var value = obj[step]
            if (cb.call(arg2, value, step, obj)) {
                return step
            }
            step++
        }
        return undefined
    }
    var arr = [1, 2, 3]
    var r = arr.myFindIndex(function(item) {
        return item > 1
    })
    console.log(r)
    
0

评论区