数组的七个 API 的简单实现

611 阅读3分钟

首先是哪个七个API?join、slice、sort、forEach、map、filter和reduce。

有些公司要求员工要三句话说清一个概念,大致就是“是什么?有什么用?怎么用?”。对于我们的学习知识,我想我们有些时候至少还得知道它是怎么来的。所以今天就来干怎么一件事,简单实现,没有在乎细节,只是功能实现而已,比如所有些像map这种的可以传第二个参数,改变this指向,在这里我就没有处理了。

废话不多说。

join

var ary = [1,2,3];
ary.join('=')
//"1=2=3"

好,你要确定你知道join的用法,现在我们来实现

Array.prototype.join = function(char) {
    let result = this[0] || '' 
    let length = this.length 
    for(let i = 0; i < length; i++) {
        result += char + this[i]
    }

    return result
}

this是Array。

slice

var ary = [1,2,3];
ary.slice(1,2)
//[2]

这是一个切片,您得确定您知道它的用法。

Array.prototype.slice = function(begin, end) {
    let result = []
    begin = begin || 0
    end = end || this.length    //这一步很重要,需要您理解
    for(let i = begin; i < end; i++) {
        result.push(this[i])
    }

    return result
}

您注意到我代码中的那行注释了吗?

因为它很重要,我必须标出来,这是为什么我们可以写如下代码的原因。

ary = Array.prototype.slice.call(likeArray);    //我们常用这种方式将类数组转化为数组

当然现在不用写这么多了,ES6给我提供了Array.from()这个API,专门用来将类数组转为真数组。

sort

这里不用快排,用选择排序。

var ary = [1,3,2];
ary.sort((a,b)=>a>b)
//(3) [1, 2, 3]

您得确定您知道它的用法,并且知道一些细节,但这里我们只是简单实现,就不在乎一些细节啦。

Array.prototype.sort = function(fn) {
    fn = fn || (a,b)=> a-b
    let roundCount = this.length - 1    //比较的轮数
    for(let i = 0; i < roundCount; i++) {
        let minIndex = this[i]
        for(let k = i + 1; k < this.length; k++) {
            if( fn.call(null, this[k], this[i]) < 0) {
                [ this[i], this[k] ] =  [ this[k], this[i] ]    //    ES6的方法

            }
        }
    }
}

forEach

var ary = [1,3,2];
ary.forEach((item)=>{
	console.log(item)
})
// 1
// 3
// 2

与for用法一样,但也有区别,您是知道它的用法的。

Array.prototype.forEach = function(fn) {
    for(let i = 0; i < this.length; i++) {
       fn.call(undefined, this[i], i, this)
    }
}

for循环没有作用域或说只有一个。而forEach因为传了一个函数,所以遍历一项都会产生一个作用域。

map

这是一个映射,他很强大,你甚至可以不要forEach,用它就够了。我在之前的系列中已经写过一次map方法了。所以这里,还是在写一次吧。

Array.prototype.map = function(fn) {
    let result = []
    for(let i = 0; i < this.length; i++) {
        result[i] = fn.call(undefined, this[i], i, this )
    }

    return result
}

filter

Array.prototype.filter = function(fn) {
    let result = []
    let temp
    for(let i = 0; i < this.length; i++) {
        if(temp = fn.call(undefined, this[i], i, this)) {
            result.push(this[i])
        }
    }

    return result
}

reduce

reduce方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

Array.prototype.reduce = function(fn, init) {
    let result = init
    for(let i = 0; i < this.length; i++) {
        result = fn.call(undefined, result, this[i], i,this)
    }

    return result
}

好吧,就到这啦。最近玩的有点多,要早点休息,前几天报名的方应杭的vue造轮子课都落课了,https://xiedaimala.com/courses/6d63da67-6eea-4711-aeb4-0c3a949341dc。(我推荐您也可以了解一下)学习啊,满脑子全是学习。