美文网首页前端开发那些事儿
手动封装ES5数组新增方法-indexOf和lastIndexO

手动封装ES5数组新增方法-indexOf和lastIndexO

作者: 深度剖析JavaScript | 来源:发表于2020-08-12 09:01 被阅读0次

一个版本的跟新迭代必然会摈弃一些旧的东西,同时新增一些实用的东西。下面一起来看ES5中数组的新增方法

首先,我们将这些方法归类:

  • 2个索引方法:indexOf() 和 lastIndexOf()
  • 5个迭代方法:forEach()、map()、filter()、some()、every()
  • 2个归并方法:reduce()、reduceRight()

这里我们先来看前面两个方法的模拟实现

indexOf()和lastIndexOf()

这两个方法都是用于返回元素在数组中第一次被查找到的索引位置,如果没有找到,那么返回-1。
都接收两个参数:
1. 第一个参数是要查找的东西
2. 第二个参数是查找起点位置的索引,如果缺省或是格式不正确,那么默认为0。第二个参数可选
区别就是一个从前往后找,一个从后往前找

  • 基本使用
    一起来看例子,先定义一个数组:
var arr = [1, 2, 3, 4, 5, 6];

indexOf():从数组的开头开始向后查找。

console.log(arr.indexOf(3));//2   只传一个值,默认从第0项开始查找  知道返回索引
console.log(arr.indexOf(10));//-1 没找到返回-1
console.log(arr.indexOf());//-1   什么都不传,返回-1
console.log(arr.indexOf(3,'a'));//2   传两个值,第二个格式不正确,默认从第0项开始查找
console.log(arr.indexOf(3,2));//2   从第2项开始查找,返回找到位置

lastIndexOf(): 从数组的末尾开始向前查找。

console.log(arr.lastIndexOf(3));//2    值传一个值,表示从倒数第一位开始查找,找到返回索引
console.log(arr.lastIndexOf(7));//-1  没找到返回-1
console.log(arr.lastIndexOf());//-1   什么都不传,返回-1
console.log(arr.lastIndexOf(3,'a'));//-1   
console.log(arr.lastIndexOf(1,'a'));//0   传两个值,第二个格式不正确,默认从倒数最后一位开始查找,即只是找一位
console.log(arr.lastIndexOf(3,2));//2   第二位是正常数值,从该位置开始向前查找,没有找到返回-1  

观察发现除了一个从前往后找,一个从后往前找的区别外,我们还发现一个小区别,就是当第二个参数错误时,都是默认从0位开始查找,导致indexOf()查找整个数组,lastIndexOf只查找第0位。
查找对比时,会使用全等操作符"===", 要求必须完全相等,否则返回-1。

console.log(arr.indexOf('1'))//-1   这里"1"和1是不相等

另外第二个参数也不存在隐式类型转换

console.log(arr.lastIndexOf(3,'1'));//-1 
  • 模拟封装_indexOf
Array.prototype._indexOf = function (val, start) {
  var self = this;
  if (arguments.length == 0) {
    return -1;
  }
  if (arguments.length == 1) {
    return _searchFromZero();
  }
  if (arguments.length >= 2) {
    // 这里得处理第二个参数:接受负值的情况 和 接受错误值的情况(判断是不是数字)
    if (typeof start !== "number" || isNaN(start)) {
      return _searchFromZero();
    }
    //否则就是数字,数字分正数和负数,负数可以通过运算转成正数
    if (typeof start === "number" && !isNaN(start)) {
      start = start >= 0 ? start : start + this.length;
      var temp = 0;
      for (var i = start; i < this.length; i++) {
        temp++;
        if (this[i] === val) {
          return start + temp - 1;//变成下标
        }
      }
      return -1;
    }
  }
  function _searchFromZero() {
    for (var i = 0; i < self.length; i++) {
      if (self[i] === val) {
        return i;
      }
    }
    return -1;
  }
}

测试

// test code
console.log(arr._indexOf(3));//2   只传一个值,默认从第0项开始查找
console.log(arr._indexOf(7));//-1 没找到返回-1
console.log(arr._indexOf());//-1   什么都不传,返回-1
console.log(arr._indexOf(3, 'a'));//2   第二个格式不正确,从第0项开始查找
console.log(arr._indexOf(3, 0));//2   
console.log(arr._indexOf(3, -4));//2   
console.log(arr._indexOf(3, -5));//2   
console.log(arr._indexOf(3, 100));//-1  

模拟实现了indexOf的基本使用!

  • 模拟封装_lastIndexOf
Array.prototype._lastIndexOf = function (val, start) {
  var self = this;
  if (arguments.length == 0) {
    return -1;
  }

  if (arguments.length == 1) {
    return _searchFromEnd();
  }
  function _searchFromEnd() {
    for (var i = self.length - 1; i > 0; i--) {
      if (self[i] === val) {
        return i;
      }
    }
    return -1;
  }
  if (arguments.length >= 2) {
    //  传两个值,第二个格式不正确,默认从倒数最后一位即第0位开始查找,只是找一位.第1位是就返回0,不是返回-1
    if (typeof start !== "number" || isNaN(start)) {
      return self[0] === val ? 0 : -1;
    }
    // 否则就是数字,这里应该也有正负,所以也得转,正数是第几位。
    if (typeof start === "number" && !isNaN(start)) {
      // 到时第start位,正数是第几位呢
      start = -start + self.length;
      // 正后也有可能是负数或者正数,统一转为正。
      start = start >= 0 ? start : start + self.length;
      // console.log(start)
          // var temp = 0;
          for (var i = start; i > 0; i--) {
            // temp++;
            if (self[i] === val) {
              return i;//变成下标
            }
          }
          return -1;
    }
  }
}

测试

console.log(arr._lastIndexOf());//-1   什么都不传,返回-1
console.log(arr._lastIndexOf(3));//2    值传一个值,表示从倒数第1位开始查找
console.log(arr._lastIndexOf(3, 'a'));//-1   
 console.log(arr._lastIndexOf(1,'a'));//0   第二个格式不正确,默认从倒数最后一位开始查找,即只是对比数组第0位置。
console.log(arr._lastIndexOf(3, 2));//2   第二位是正常数值,从该位置开始向前查找

模拟实现了lastIndexOf的基本使用!

参考文献:
es5新增的数组方法—作者:叶子_o
聊一聊ES5数组(Array)新增的那些方法—作者:三色堇
js判断类型为数字的方法实现总汇——原生js判断isNumber()

相关文章

网友评论

    本文标题:手动封装ES5数组新增方法-indexOf和lastIndexO

    本文链接:https://www.haomeiwen.com/subject/xoujdktx.html