JS模拟实现ECMAScript5新增的十个数组方法

作者:代码拾荒

时间:2026-10-21

浏览:548

本文详细解析并模拟实现了ECMAScript5新增的十个数组方法,包括isArray、indexOf、lastIndexOf、forEach、every、some、map、filter、reduce及reduceRight。通过原生JavaScript代码还原各方法的核心逻辑,重点处理稀疏数组与缺失成员,帮助开发者深入理解数组API底层机制。

文章目录

ECMAScript5数组方法概述

ECMAScript5标准引入了十个新的数组方法,这些功能仅在IE9及更高版本的浏览器中原生支持。下文将对这些方法进行模拟实现。

类型检测与查找方法

一、Array.isArray(element)

该函数用于检测传入参数是否为数组类型,若为数组则返回true,否则返回false。

Array.isArray模拟实现


Array.newIsArray = function(element){
  return Object.prototype.toString.call(element).slice(8,-1).toLocaleLowerCase() === 'array';
}

二、.indexOf(element)

此方法用于查找指定元素在数组中的索引位置。若找到则返回该位置索引,未找到则返回-1。需注意,该方法无法用于查找undefined值。

indexOf方法常与按位非运算符~配合使用。~运算符会对数字取反并减一,因此-1经转换后变为0。在布尔判断中,0会被隐式转换为false,从而实现便捷的查找判断。

indexOf与lastIndexOf模拟


Array.prototype.newIndexOf = function(element){
  var index = -1;
  for(var i = 0; i < this.length; i++){
    if(this[i] === element && this[i] !== undefined){
      index = i;
      break;
    }
  }
  return index;
};
var a = [1,2,3,4,,,5];
console.log(a.newIndexOf(undefined));

三、lastIndexOf(element)

该方法的功能与返回值与indexOf相同,区别在于搜索方向是从数组末尾向开头进行。


Array.prototype.newLastIndexOf = function(element){
  var index = -1;
  for(var i = this.length - 1; i >= 0; i--){
    if(this[i] === element && this[i] !== undefined){
      index = i;
      break;
    }
  }
  return index;
};
var a = [1,2,3,4,5,2,,,3];
console.log(a.newLastIndexOf(undefined));

数组遍历方法

四、forEach(function(element, index, array){})

用于遍历数组,接收一个回调函数作为参数。回调函数包含三个参数:当前元素、当前索引及整个数组。此方法会跳过数组中的空位(缺失成员),且不会修改原数组。

forEach模拟实现


Array.prototype.newForEach = function(fn){
  for(var i = 0; i < this.length; i++){
    if(i in this){
      fn(this[i], i, this);
    }
  }
};
var a = [1,2,3,undefined,undefined,4,5,2,3];
a.forEach(function(e, i, arr){
  console.log(e, i, arr);
})

五、every(function(element, index, array){})

使用提供的回调函数遍历数组。仅当所有回调函数均返回true时,every方法才返回true,否则返回false。该方法会跳过空位,不修改原数组。

every与some模拟


Array.prototype.newEvery = function(fn){
  var status = true;
  for(var i = 0; i < this.length; i++){
    if(i in this){
      if(!(status = !!fn(this[i], i, this))){
        break;
      }
    }
  }
  return status;
};
var a = [1,2,3,4,5,2,undefined,,3];
console.log(a.newEvery(function(){
  console.log(arguments);
  return 1;
}));

六、some(function(element, index, array){})

使用提供的回调函数遍历数组。只要有一个回调函数返回true,some方法即返回true,否则返回false。该方法会跳过空位,不修改原数组。


Array.prototype.newSome = function(fn){
  var status = false;
  for(var i = 0; i < this.length; i++){
    if(i in this){
      if(status = !!fn(this[i], i, this)){
        break;
      }
    }
  }
  return status;
};
var a = [1,2,3,4,5,2,undefined,,3];
console.log(a.newSome(function(){
  console.log(arguments);
  return 0;
}));

七、map(function(element, index, array){})

使用提供的回调函数遍历数组,并将每次调用的返回值组成一个新数组返回。该方法会跳过空位,但新数组中会保留缺失成员的索引位置,且不修改原数组。

map与filter模拟


Array.prototype.newMap = function(fn){
  var array = new Array(this.length);
  for(var i = 0; i < this.length; i++){
    if(i in this){
      array[i] = fn(this[i], i, this);
    }
  }
  return array;
};
var a = [1,2,3,4,5,2,undefined,,3];
console.log(a.newMap(function(element, index, array){
  console.log(arguments);
  return element;
}))

八、filter(function(element, index, array){})

使用提供的回调函数遍历数组,返回一个新数组,其中包含所有使回调函数返回true的元素。该方法会跳过空位,且不修改原数组。


Array.prototype.newFilter = function(fn){
  var array = [];
  for(var i = 0; i < this.length; i++){
    if((i in this) && fn(this[i], i, this)){
      array.push(this[i]);
    }
  }
  return array;
};
var a = [1,2,3,4,5,2,undefined,,3];
console.log(a.newFilter(function(element, index, array){
  console.log(arguments);
  return element;
}))

九、reduce(function(accumulator, currentValue, currentIndex, array){})

使用提供的回调函数从左至右遍历数组,返回最后一次回调函数调用的结果。该方法会跳过空位,且不修改原数组。

reduce与reduceRight模拟


Array.prototype.newReduce = function(fn){
  if(this.length === 0){
    throw new TypeError('Reduce of empty array with no initial value');
  }
  var result;
  for(var i = 0; i < this.length; i++){
    if(i in this){
      if(!result){
        result = this[i];
      }else{
        result = fn(result, this[i], i, this);
      }
    }
  }
  return result;
};
var a = [,,1,2,3,4,,6,7];
console.log(a.newReduce(function(a,b){
  console.log(arguments);
  return a + b;
}))

十、reduceRight(function(accumulator, currentValue, currentIndex, array){})

此方法的功能与reduce相同,唯一区别在于遍历方向是从右至左。


Array.prototype.newReduceRight = function(fn){
  if(this.length === 0){
    throw new TypeError('Reduce of empty array with no initial value');
  }
  var result;
  for(var i = this.length - 1; i >= 0; i--){
    if(i in this){
      if(!result){
        result = this[i];
      }else{
        result = fn(result, this[i], i, this);
      }
    }
  }
  return result;
};
var a = [,,1,2,3,4,,6,7];
console.log(a.newReduceRight(function(a,b){
  console.log(arguments);
  return a + b;
}))

以上介绍了JS模拟实现ECMAScript5新增数组方法的相关内容,希望能为读者提供帮助。如有疑问欢迎留言,小编会及时回复。感谢对本站的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章