JS模拟实现ECMAScript5新增的十个数组方法
本文详细解析并模拟实现了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新增数组方法的相关内容,希望能为读者提供帮助。如有疑问欢迎留言,小编会及时回复。感谢对本站的支持!
JavaScript异步发送HTTP请求时怎么优雅地处理错误
2026-11-05 17:10:44
5款主流JS在线运行工具对比:CodePen、JSFiddle与StackBlitz怎么选
2026-11-05 17:04:04
JavaScript入门书籍避坑:这些书不适合初学者
2026-11-05 16:31:15
JS使用Math.round实现保留两位小数的原理与代码
2026-11-05 15:35:55
JavaScript 原生 Date 对象怎么实现日期加减
2026-11-05 14:30:00
