模拟实现 JavaScript 数组方法

By bobo 2021-12-21 18:06:30 文章分类:JavaScript

forEach

Array.prototype.myForEach = function (cb, thisArg) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }

    var _arr = this
    thisArg = thisArg || window
    for (var i = 0, len = _arr.length; i < len; i++) {
        cb.call(thisArg, _arr[i], i, _arr)
    }
}

arr.myForEach(function (item, index, array) {
    console.log(item, index, array)
})

map

Array.prototype.myMap = function (cb, thisArg) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }
    thisArg = thisArg || window
    var _arr = this,
        res = []

    for (var i = 0, len = _arr.length; i < len; i++) {
        res.push(cb.call(thisArg, _arr[i], i, _arr))
    }

    return res
}

arr.myMap(function (item, index, array) {
    console.log(item, index, array)
    return item + 1
})

filter

Array.prototype.myFilter = function (cb, thisArg) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }
    thisArg = thisArg || window
    var _arr = this,
        res = []

    for (var i = 0, len = _arr.length; i < len; i++) {
        if (cb.call(thisArg, _arr[i], i, _arr)) {
            res.push(_arr[i])
        }
    }
    return res
}

arr.myFilter(function (item, index, array) {
    console.log(item, index, array)
    return item > 3
})

some


Array.prototype.mySome = function (cb, thisArg) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }
    thisArg = thisArg || window
    var _arr = this,
        flag = false

    for (var i = 0, len = _arr.length; i < len; i++) {
        if (cb.call(thisArg, _arr[i], i, _arr)) {
            flag = true
            break
        }
    }

    return flag
}
arr.mySome(function (item, index, array) {
    console.log(item, index, array)
    return item === 3
})

every

Array.prototype.myEvery = function (cb, thisArg) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }
    thisArg = thisArg || window
    var _arr = this,
        flag = true

    for (var i = 0, len = _arr.length; i < len; i++) {
        if (!cb.call(thisArg, _arr[i], i, _arr)) {
            flag = false
            break
        }
    }

    return flag
}

arr.myEvery(function (item, index, array) {
    console.log(item, index, array)
    return item > 3
})

reduce

Array.prototype.myReduce = function (cb, accumulator) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }

    var _arr = this,
        i = 0,
        len = _arr.length

    if (accumulator === undefined) {
        if (len === 0) {
            throw new Error('initVal and Array.length > 0 need one')
        }

        accumulator = arr[i]
        i++
    }

    for (; i < len; i++) {
        accumulator = cb(accumulator, _arr[i], i, _arr)
    }

    return accumulator
}

arr.myReduce(function (res, cur, index, array) {
    console.log(res, cur, index, array)
    return res + cur
}, 0)

findIndex

Array.prototype.myFindIndex = function (cb, thisArg) {
    if (this == null) {
        throw new TypeError("Cannot read property 'myForEach' of null")
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a Function')
    }

    var _arr = this,
        _index = -1

    for (var i = 0, len = _arr.length; i < len; i++) {
        if (cb.call(thisArg, _arr[i], i, _arr)) {
            _index = i
            break
        }
    }
    return _index
}

arr.myFindIndex(item => item === 3)

indexOf

Array.prototype.myIndexOf = function (val, start) {
    var _arr = this,
        len = _arr.length,
        _index = -1

    start = start || 0

    if (!val || len === 0 || start > len) {
        return _index
    }

    if (typeof start !== 'number' || isNaN(start)) {
        return _index
    }

    start = start >= 0 ? start : start + len
    var temp = 0
    for (var i = start; i < len; i++) {
        temp++
        if (_arr[i] === val) {
            _index = start + temp - 1
            break
        }
    }
    return _index
}