js数组常用函数实现

192 阅读3分钟

一、forEach

1、参数

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
  • callback:数组中每个元素的执行函数,总共接受这几个参数:currentValue(当前的数组元素,必选参数) index(索引,可选参数) array(传入的数组,可选参数)
  • thisArg:可选参数,执行callback的时候,用作this的值,可以看下面的列子
let arr = ['a', 'b', 'c']
let thisArr = [1, 2, 3]
arr.forEach(function(item, index, array) {
    console.log('this', this)
}, thisArr)

2、返回值

返回undefined,由于是在原数组上操作的,因此会改变原数组

3、实现

//call 形式
Array.prototype.myForEach = function (cb, thisArg) {
  const len = this.length;
  for (let i = 0; i < len; i++) {
    cb.call(thisArg, this[i], i, this);
  }
};
//bind形式
Array.prototype.myForEach = function (cb, thisArg) {
  const len = this.length;
  cb = cb.bind(thisArg);
  for (let i = 0; i < len; i++) {
    cb(this[i], i, this);
  }
};
//apply形式
Array.prototype.myForEach = function (cb, thisArg) {
  const len = this.length;
  for (let i = 0; i < len; i++) {
    cb.apply(thisArg, [this[i], i, this]);
  }
};

4、github地址

forEach代码

二、find

1、参数

arr.find(callback[, thisArg])
  • callback:执行函数,总共三个参数,element(当前元素) index(索引,可选参数) array(传入的操作数组,可选参数)
  • thisArg:可选参数,用作this的值

2、返回值

返回第一个满足条件的元素的值,找不到的话就返回undefined,该方法不会改变原数组

3、实现

Array.prototype.myFind = function (cb, thisArg) {
  cb = cb.bind(thisArg);
  for (let i = 0; i < this.length; i++) {
    if (cb(this[i])) {
      return this[i];
    }
  }
};

4、github地址

find代码

三、findIndex

1、参数

arr.findIndex(callback[, thisArg])
  • callback:回调函数,总共有三个参数,element(当前元素) index(索引,可选参数) array(传入的数组,可选参数)
  • thisArg:可选参数,用作this的值

2、返回值

返回第一个满足条件的索引,找不到则返回-1,不会改变原数组

3、实现

Array.prototype.myFindIndex = function (cb, thisArg) {
  cb = cb.bind(thisArg);
  for (let i = 0; i < this.length; i++) {
    if (cb(this[i])) {
      return i;
    }
  }
  return -1;
};

4、github地址

findIndex代码

四、filter

1、参数

arr.filter(callback(element[, index[, array]])[, thisArg])
  • callback:回调函数
  • thisArg:可选参数,用作this值

2、返回值

返回数组所有满足条件的元素,否则返回个空数组,不会改变原数组

3、实现

Array.prototype.myFilter = function (cb, thisArg) {
  const newArr = [],
    len = this.length;
  cb = cb.bind(thisArg);
  if (len) {
    for (let i = 0; i < len; i++) {
      if (cb(this[i])) {
        newArr.push(this[i]);
      }
    }
  }
  return newArr;
};

4、github地址

filter代码

五、indexOf

1、参数

arr.indexOf(searchElement[, fromIndex])
  • searchElement:要查找的元素
  • fromIndex:可选参数,查找开始的位置

2、返回值

返回要查找元素的索引,否则返回-1,不会改变原数组

3、实现

Array.prototype.myIndexOf = function (param, start = 0) {
  const len = this.length;
  if (start >= len) return -1;
  if (start < 0) {
    start = start + len < 0 ? 0 : start + len;
  }
  for (let i = start; i < len; i++) {
    if (this[i] === param) return i;
  }
  return -1;
};

4、github地址

indexOf代码

六、every

1、参数

arr.every(callback(element[, index[, array]])[, thisArg])
  • callback:回调函数
  • thisArg: 可选参数,用作this的值

2、返回值

如果数组每一项都满足回调函数,则返回true,否则返回false,不改变原数组

3、实现

//every
Array.prototype.myEvery = function (cb, thisArg) {
  cb = cb.bind(thisArg);
  const len = this.length;
  if (len === 0) return true;
  for (let i = 0; i < len; i++) {
    if (!cb(this[i])) {
      return false;
    }
  }
  return true;
};

4、github地址

every代码

七、some

1、参数

arr.some(callback(element[, index[, array]])[, thisArg] )
  • callback:回调函数
  • thisArg: 可选参数,用作this的值

2、返回值

数组只要有一项满足回调函数,就返回true, 否则返回false,不改变原数组

3、实现

Array.prototype.mySome = function (cb, thisArg) {
  cb = cb.bind(thisArg);
  const len = this.length;
  for (let i = 0; i < len; i++) {
    if (cb(this[i])) {
      return true;
    }
  }
  return false;
};

4、github地址

some代码

八、includes

1、参数

arr.includes(valueToFind[, fromIndex])
  • valueToFind:寻找的元素
  • fromIndex:寻找开始的位置

2、返回值

返回找到元素的索引,没找到则返回-1,不会改变原数组

3、实现

Array.prototype.myIncludes = function (param, start = 0) {
  const len = this.length;
  if (start >= this.length) {
    return false;
  } else if (start < 0) {
    start = start + len < 0 ? 0 : start + len;
  }
  if (Number.isNaN(param)) {
    for (let i = start; i < len; i++) {
      if (Number.isNaN(this[i])) return true;
    }
  } else {
    for (let i = start; i < len; i++) {
      if (this[i] === param) return true;
    }
  }
  return false;
};

4、github地址

includes代码

九、fill

1、参数

arr.fill(value[, start[, end]])
  • value:要填充到数组的元素值
  • start:开始的位置
  • end:结束的位置

2、返回值

返回的是填充好的数组,会改变原数组

3、实现

Array.prototype.myFill = function (value, start = 0, end = this.length) {
  const len = this.length;
  start = start < 0 ? start + len : start;
  end = end < 0 ? end + len : end;
  for (let i = start; i < end; i++) {
    this[i] = value;
  }
  return this;
};

4、github地址

fill代码

十、concat

1、参数

old_array.concat(value1[, value2[, ...[, valueN]]])
  • valueN表示要被连接的参数

2、返回值

返回一个新数组,不影响原数组

3、实现

// 第一种实现
Array.prototype.myConcat = function () {
  const data = [...arguments],
    newArr = JSON.parse(JSON.stringify(this));
  for (let i = 0; i < data.length; i++) {
    newArr.push(data[i]);
  }
  return newArr;
};
// 第二种实现
Array.prototype.myConcat = function () {
  return [...this, ...arguments].flat();
};

4、github地址

concat代码

十一、slice

1、参数

arr.slice([begin[, end]])
  • begin 可选参数,起始位置,负数的话则是从后往前,省略的话就是从0开始
  • end 可选参数,终止位置,省略就是到数组结尾

2、返回值

返回一个从begin 到 end 的数组

3、实现

Array.prototype.mySlice = function (start = 0, end = this.length) {
  const arr = [],
    len = this.length;
  if (start >= len) return [];
  start = start < 0 ? (len + start < 0 ? 0 : start + len) : start;
  end = end < 0 ? (len + end < 0 ? 0 : end + len) : end;
  for (let i = start; i < end; i++) {
    arr.push(this[i]);
  }
  return arr;
};

4、github地址

slice代码

十二、splice

1、参数

array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
  • start 修改的起始位置,超出数组的长度,就从数组后面开始添加内容,负数的话,就是从末尾往前
  • start deleteCount 0或者负数,表示添加元素,正数表示删除
  • item1,item2...(可选) 表示要添加的元素,如果没有指定,表示要删除的元素

2、返回值

由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组

3、实现

Array.prototype.mySplice = function (index, deleCount) {
  let arrLeft = [],
    arrRight = [],
    arrAdd = [],
    deleteArr = [];
  for (let i = 0; i < this.length; i++) {
    if (i < index) {
      arrLeft.push(this[i]);
    } else if (i >= index + deleCount) {
      arrRight.push(this[i]);
    } else {
      deleteArr.push(this[i]);
    }
  }
  for (let i = 2; i < arguments.length; i++) {
    arrAdd.push(arguments[i]);
  }
  [...arrLeft, ...arrAdd, ...arrRight].forEach((item, index) => {
    this[index] = item;
  });
  return deleteArr;
};

4、github地址

splice代码

十三、map

1、参数

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
    // Return element for new_array
   }[, thisArg])
  • callback 回调函数,包含三个参数:currentValue index array
  • thisArg 可选参数,绑定的this值

2、返回值

返回执行回调函数的新数组,不影响原数组

3、实现

Array.prototype.myMap = function (cb, thisArg) {
  const newArr = [];
  cb = cb.bind(thisArg);
  for (let i = 0; i < this.length; i++) {
    newArr.push(cb(this[i]));
  }
  return newArr;
};

4、github地址

map代码

十四、reduce

1、参数

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
  • callback 回调函数,包含三个参数:accumulator(累加器累计的返回值,是上一次调用回调函数返回的累加值,或者是初始值) currentValue(当前正在处理的数值) index(可选参数,索引) array(可选参数,当前操作的数组)
  • initialValue 初始值

2、返回值

函数累计处理的结果,不影响原数组

3、实现

Array.prototype.myReduce = function (cb, initVal) {
  const len = this.length;
  if (len) {
    const currentIndex = initVal ? 0 : 1;
    let accumulator = initVal || this[0];
    for (let i = currentIndex; i < len; i++) {
      accumulator = cb(accumulator, this[i], i, this);
    }
    return accumulator;
  }
};

4、github地址

reduce代码

十五、reverse

1、参数

无参数

2、返回值

返回一个倒序的新数组,会改变原数组

3、实现

Array.prototype.myReverse = function () {
  const len = this.length;
  for (let i = 0; i < len / 2; i++) {
    const temp = this[i];
    this[i] = this[len - 1 - i];
    this[len - 1 - i] = temp;
  }
  return this;
};

4、github地址

reverse代码

十六、flat

1、参数

var newArray = arr.flat([depth])
  • depth 要提取的嵌套数组的深度,默认为1

2、返回值

返回一个处理过的新数组,不会影响原数组

3、实现

Array.prototype.myFlat = function (dep = 1) {
  let current = this,
    count = 0;
  if (!current.length || dep === 0) return current;
  try {
    while (count++ < dep) {
      if (Array.isArray(current)) {
        current = current.reduce((prev, cur) => prev.concat(cur), []);
      } else {
        return current;
      }
    }
  } catch (err) {
    throw err;
  }
  return current;
};

4、github地址

flat代码

十七、join

1、参数

arr.join([separator])
  • separator 分隔符

2、返回值

返回一个由分隔符分割的字符串,不会改变原数组

3、实现

Array.prototype.myJoin = function (val) {
  const string = "",
    len = this.length;
  for (let i = 0; i < len; i++) {
    string += this[i];
  }
  return string;
};

4、github地址

join代码

十八、sort

1、参数

arr.sort([compareFunction])
  • compareFunction  可选参数,是传入的排序函数

2、返回值

返回排好序的数组,会改变原数组

3、实现

Array.prototype.mySort = function (cb) {
  const len = this.length;
  if (len <= 1) return this;
  if (cb === undefined) {
    for (let i = 0; i < len; i++) {
      for (let j = 0; j < len - i - 1; j++) {
        [this[j], this[j + 1]] =
          String(this[j]) > String(this[j + 1])
            ? [this[j + 1], this[j]]
            : [this[j], this[j + 1]];
      }
    }
  } else if (cb instanceof Function) {
    for (let i = 0; i < len; i++) {
      for (let j = 0; j < len - i - 1; j++) {
        [this[j], this[j + 1]] = cb(this[j], this[j + 1])
          ? [this[j + 1], this[j]]
          : [this[j], this[j + 1]];
      }
    }
  }
  return this;
};

4、github地址

sort代码

总结

函数名参数this值返回值是否改变原数组
forEach(callback(currentValue, index, array),this)可绑定this 值无返回值改变
find(callback(element, index, array), this)可绑定this 值返回数组中第一个满足条件的元素,否则返回undefined不改变
findIndex(callback(element, index, array), this)可绑定this 值返回数组中第一个满足条件的元素的索引,否则返回-1不改变
filter(callback(element, index, array), this)可绑定this 值返回满足条件的新数组,否则返回空数组不改变
indexOf(value, index)不可绑定返回满足条件的索引值,否则返回-1不改变
every(callback(element, index, array), this)可绑定this 值返回一个布尔值,若数组中每一项都满足条件则返回true,否则返回false不改变
some(callback(element, index, array), this)可绑定this 值返回布尔值,若数组中有一项满足条件就返回true,否则返回false不改变
includes(value, index)不可绑定返回布尔值,找到返回true,否则返回false不改变
fill(value, start, end)不可绑定返回填充后的数组不改变
concat(value1....valueN)不可绑定返回连接后的数组不改变
slice(begin, start)不可绑定返回被提取元素的新数组不改变
splice(start, index, item1...itemN)可绑定this 值返回被删除的元素,如果是新增,则返回空数组改变
map(callback(currentValue, index, array), this)可绑定this 值返回转化后的新数组不改变
reduce(callback(accumulator, currentValue, index, array), this)可绑定this 值返回转化后的新数组不改变
reverse无参数不可绑定返回倒置后的数组改变
flat(depth)不可绑定返回一维数组不改变
join(sperator)不可绑定返回由分隔符分割的字符串不改变
sort(callback)不可绑定返回排好序的数组改变

参考链接