一个版本的跟新迭代必然会摈弃一些旧的东西,同时新增一些实用的东西。下面一起来看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()
网友评论