平平无奇的前端总结:常见的数组方法(ES5)

394 阅读1分钟

ES5中常见数组方法的实现,记录于此,如有疑问,欢迎指正。

forEach

Array.prototype.forEach = function (cb, context) {
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    if(typeof cb !== 'function'){
        throw new TypeError(cb + ' is not a function')
    }
    let O = Object(this), k = 0, len = O.length >>> 0;
    while(k < len){
        if(k in O){
            cb.call(context, O[k], k, O)
        }
        k++
    }
}

reduce

Array.prototype.reduce = function(cb, initVal){
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    if(typeof cb !== 'function'){
        throw new TypeError(cb + ' is not a function')
    }
    let O = Object(this), len = O.length >>> 0;
    if(arguments.length === 1 && len === 0) throw new TypeError('Reduce of empty array with no initial value')
    let acc, k = 0;
    if(arguments.length >= 2){
        acc = arguments[1]
    }else{
        // 稀疏数组
        while(true){
            if(k in O){
                acc = O[k++];
                break;
            }
            if(++k >= len) throw new TypeError('Reduce of empty array with no initial value')
        }
    }
    while(k < len){
        if(k in O){
            acc = cb.call(undefined, acc, O[k], k, O)
        }
        k++
    }
    return acc
}

map

Array.prototype.map = function(cb, context){
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    if(typeof cb !== 'function'){
        throw new TypeError(cb + ' is not a function')
    }
    let O = Object(this), len = O.length >>> 0, k = 0;
    let result = new Array(len);
    while(k < len){
        if(k in O){
            result[k] = cb.call(context, O[k], k, O)
        }
        k++
    }
    return result
}

filter

Array.prototype.filter = function(cb, context){
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    if(typeof cb !== 'function'){
        throw new TypeError(cb + ' is not a function')
    }
    let O = Object(this), len = O.length >>> 0, k = 0;
    let result = [];
    while(k < len){
        if(k in O){
            let val = O[k]
            if(cb.call(context, val, k, O)){
                result.push(val)
            }
        }
        k++
    }
    return result
}

every

Array.prototype.every = function(cb, context){
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    if(typeof cb !== 'function'){
        throw new TypeError(cb + ' is not a function')
    }
    let O = Object(this), len = O.length >>> 0, k = 0;
    while(k < len){
        if(k in O){
            if(!cb.call(context, O[k], k, O)){
                return false
            }
        }
        k++
    }
    return true        
}

some

Array.prototype.some = function(cb, context){
    if (this == null) {
        throw new TypeError('this is null or not defined')
    }
    if (typeof cb !== 'function') {
        throw new TypeError(cb + ' is not a function')
    }
    let O = Object(this), len = O.length >>> 0, k = 0;
    while(k < len){
        if(k in O && cb.call(context, O[k], k, O)){
            return true
        }
        k++
    }
    return false
}

indexOf

Array.prototype.indexOf = function(target, start){
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    let O = Object(this), len = O.length >>> 0, k = 0;
    if(len === 0) return -1;
    if(isNaN(start)){
        start = 0
    }else if(start !== 0 && start !== (1/0) && start !== -(1/0)){
        start = (start > 0 || -1) * Math.floor(Math.abs(start))
    }
    if(start > len) return -1
    k = start >= 0? start : Math.max(len - Math.abs(start))
    while(k < len){
        if(k in O && O[k] === target){
            return k        
        }
        k++
    } 
    return -1
}

lastIndexOf

Array.prototype.lastIndexOf = function(target, start){
    if(this == null){
        throw new TypeError('this is null or not defined')
    }
    let O = Object(this), len = O.length >>> 0;
    if(len === 0) return -1
    start = len
    if(arguments.length > 1){
        start = Number(arguments[1])
        if(start !== start){
            start = 0
        }else if(start !== 0 && start !== (1/0) && start !== -(1/0)){
            start = (start > 0 | -1) * Math.floor(Math.abs(start))
        }
    }
    let k = start >= 0? Math.min(start, len - 1) : len - Math.abs(start)
    for(;k >=0; k--){
        if(k in O && O[k] === target){
            return k
        }
    }
    return -1
}

篇二,以上。

5.webp