JS 中数组常用方法以及它的原理实现(二)

开始

上一节,对数组的5个API 进行了总结整理,下面接着根据MDN 上的顺序整理。

数组方法

Array.prototype.every()

作用

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值,数组为空返回true。

应用

console.log([].every(a=>a>1));//true
console.log([1,2,4].every(a=>a>1)) //false
console.log([1,2,4].every(a=>a>0)) //true
console.log([1,2,4]._every(function (a){ return a>this.n},{n:0}));//true

以前只知道传callback 参数,但是还有一个传参 thisArg,表示的是执行callback的this值,加上了thisArg参数,callback就不要用箭头函数了,因为箭头函数的this无法改变。

实现

思路

  • 在数组原型上定义方法。
  • 数组为空永远返回true。
  • 传入了thisArg 参数要更改回调函数的this指向。

代码实现

Array.prototype._every=function (callback,thisArg) {
    if(typeof callback!='function')
    {
        throw new TypeError('callback is not a function')
    }
    
    let target=this,res=true;
    let context=thisArg ||this;
    for(let i=0;i

测试

测试得到和原生相同的结果

console.log([]._every(a=>a>1));//true
console.log([1,2,4]._every(a=>a>1)) //false
console.log([1,2,4]._every(a=>a>0)) //true
console.log([1,2,4]._every(function (a){ return a>this.n},{n:0}));//true

Array.prototype.filter()

作用

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。也就是数组内容过滤。

应用

var a=[1,2,3,5];
console.log(a.filter((item)=>item>2));//[3,5]
console.log(a.filter((item)=>item>this.n,{n:2})); //[]
console.log(a.filter(function(item){
    return item>this.n;
},{n:2}));// [3,5]

实现

下面就来具体实现该方法,其实很简单,就是对数组内容进行过滤,符合条件的加入新数组。

思路

  • 在数组原型上定义方法。
  • 产生一个新数组,不能影响原数组的值。
  • 传入了thisArg 参数要更改回调函数的this指向。

代码实现

Array.prototype._filter=function (callback,thisArg) {
    
    if(typeof callback!='function')
    {
        throw new TypeError('callback is not a function')
    }
   //得到上下文
    let context=thisArg ||this;
    //返回新数组
    let target=this,res=[];
    for(let i=0;i

测试
总体来说很简单,就是要记住还有 thisArg 这个参数

var a=[1,2,3,5];
console.log(a._filter((item)=>item>2)); // [3,5]
console.log(a._filter((item)=>item>this.n,{n:2})); //[]
console.log(a._filter(function(item){
    return item>this.n;
},{n:2}))   //[3,5]

Array.prototype.find()

作用

find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。

注意只是返回的第一个值,其中还有一个Array.prototype.findIndex(),lian是返回的是第一个符合条件的索引,这个方法就不做介绍了。

实现

思路

  • 在数组原型上定义该方法。
  • 两个参数,callback 和 thisArg(回调函数的this指向)。
  • 不要改变原数组。
  • 没有结果返回 undefined

代码实现

Array.prototype._find=function (callback,thisArg) {
    if(typeof callback!='function')
    {
        throw new TypeError('callback is not a function')
    }
    //上下文
    let context=thisArg || this;
    let target=this;
    for(let i=0;i

测试

很简单的一个API,不做太多解释了,findIndex 方法和它差不多,只是返回的是索引,没有符合条件的返回的是-1。

const found = array1._find(element => element > 1000);

console.log(found);

const found2=array1._find(function(element){
    return element>this.m;

},{m:100})
console.log(found2);

Array.prototype.flat()

作用

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。也就是实现数组的扁平化

这是个开发中很重要的一个API,也是相对实现难度较高的。

实例应用

console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]].flat()); //[ 1, 2, 1, [ 3, [ 4 ] ], 2, [ 3, [ 4 ] ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]].flat(2)); //[ 1, 2, 1, 3, [ 4 ], 2, 3, [ 4 ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]].flat(Infinity)); //[ 1, 2, 1, 3, 4, 2, 3, 4 ]

实现

思路

  • 在数组原型上定义该方法。
  • 参数deep 代表扁平化的深度,有深度就会用递归。
  • 默认扁平化深度为1。
  • 使用 Infinity全部扁平化
  • 不会改变原数组
Array.prototype._flat=function (deep) {
    //不传,不是大于1的数字都默认为1
    if(!deep ||typeof deep!='number'|| deep<1)
    {
        deep=1;
    }
    deep=Math.round(deep-0);
    let target=this,res=[];
   _toFlat(target,0,res);
    return res;
    function _toFlat(arr,n=0,res=[],state=false) {
        if(n>deep)
        {
            res.push(arr)
            return;
        }
        for(let i=0;i

测试

三种情况

  • 测试默认深度为1
  • 测试根据深度扁平化
  • 使用Infinity代表全部扁平化
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]]._flat()); //[ 1, 2, 1, [ 3, [ 4 ] ], 2, [ 3, [ 4 ] ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]]._flat(2)); //[ 1, 2, 1, 3, [ 4 ], 2, 3, [ 4 ] ]
console.log([1,2,[1,[3,[4]]],[2,[3,[4]]]]._flat(Infinity)); //[ 1, 2, 1, 3, 4, 2, 3, 4 ]

数组原型上还有一个flatMap 方法,感觉毫无意义,不做介绍了。

Array.prototype.forEach()

forEach() 方法对数组的每个元素执行一次给定的函数。
这个方法也很常用,但是很简单,其实一个for循环就搞定了。

代码实现

Array.prototype._forEach=function(callback,thisArg){
    if(typeof callback!='function')
    {
        throw new TypeError('callback is not a function')
    }
    let context=thisArg ||this;
    for(let i=0;i

测试

很简单的一个方法,简单测试一下即可

const array1 = ['a', 'b', 'c'];
array1._forEach(element => console.log(element));
//依次打印 a,b,c

结束

相关链接

  • 总结一:https://juejin.im/post/5f05939ef265da2306246964
    掘金地址:https://www.jianshu.com/p/f07474264563
  • MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

你可能感兴趣的:(JS 中数组常用方法以及它的原理实现(二))