关闭

重写数组迭代新方法every,filter,map,some,forEach

标签: filtermapeverysomeforEach
1737人阅读 评论(0) 收藏 举报
分类:

ECMAScript5中,对数组的操作新增的几种方法。

昨天加了一个every的方法,今天看了看,觉得很二,也很麻烦,今天想了想还是写成这个样子比较简单吧;

本来想要把这五种方法写在一个判断里面,就可以减少if语句的判断,但是又觉得不严谨,所以还是分开写吧。

如下,zylNewArray是一个包含后面数组需要用到的一些重复的方法,都放在这个里面了,这样写,把多个方法放到一个对象里面,可以减少全局的方法吧,貌似会提高一些性能。


var zylNewArray = {
	isFunction:function(func){
		return Object.prototype.toString.call(func) == '[object Function]';
	},
	NotFunctionErrorMessage : function(){
		console.log("first parameter must be a function and this function need three parameter!");
		throw new Error("first parameter must be a function");
	}
}

every和some方法

有返回值。

说起来就是个差不多对立的方法吧,他们都是返回一个布尔值,true,false。

换个大家都熟悉的说法:

every就像是and,只有在数组内的元素,都符合要求,才会返回true,只要有一个不符合,就会返回false;

some就是or,只要有一个是符合的,那么就会返回true,数组的元素,全都不符合条件时,才会返回false;

代码:

if(!Array.prototype.every){
	Array.prototype.every = function(func,context){
		if(zylNewArray.isFunction(func)){
			var that = this,
				i=0,
				len=that.length;
			for(;i<len;i++){
				if(!(func.call(context,that[i],i,that))){
					return false;
				}
			}
			return true;
		}else{
			zylNewArray.NotFunctionErrorMessage();
		}
	}
}
if(!Array.prototype.some){
	Array.prototype.some = function(func,context){
		if(zylNewArray.isFunction(func)){
			var that = this,
				i=0,
				len=that.length;
			for(;i<len;i++){
				if(func.call(context,that[i],i,that)){
					return true;
				}
			}
			return false;
		}else{
			zylNewArray.NotFunctionErrorMessage();
		}
	}
}

使用方法呢,这几个新方法的使用方法,都比较简单,支持两个参数:要在数组每一个元素上运行的函数,和(可选的)运行该函数的作用域。

var result = array.every(function(item,index,array){
	//函数体,写判断条件
	//或者其他需要对每一个数组元素操作的步骤。
},context);
result的返回值,返回是true或者false;

item代表的是,数组中的元素值。

index代表的是,当前的数组元素值,是第几个(跟大家习惯用的a[ i ]中的 i 是一个意思)。

array代表数组a,我觉得是为了嵌套循环使用吧。

这几种方法的第一个参数的输入格式都是上面的样子,更改函数体,就可以实现不同的功能了。


例子:

var a = [1,2,3,4,5];
var b = a.every(function(item,index,array){
	return item > 2;
});
var c = a.some(function(item,index,array){
	return item > 2;
});
其中,b=false,因为数组a中的元素,有小于等于2的,c=true,因为a中的元素,有大于2的。


filter方法

有返回值。

该方法会返回一个新的数组,数组的组成,即是,原数组中,符合条件的数组,不符合条件的被去掉了。

if(!Array.prototype.filter){
	Array.prototype.filter = function(func,context){
		if(zylNewArray.isFunction(func)){
			var that = this,
				i=0,
				len=that.length,
				result = [];
			for(;i<len;i++){
				if(func.call(context,that[i],i,that)){
					result.push(that[i]);
				}
			}
			return result;
		}else{
			zylNewArray.NotFunctionErrorMessage();
		}
	}
}
例子:

var a = [1,2,3,4,5];
var b = a.filter(function(item,index,array){
	return item > 2;
});
//b = [3,4,5]
返回数组中,数组元素值,大于2的所有元素。


map方法

有返回值。

返回一个新的数组,原数组不变。
新的数组是对数组内的元素,进行了处理之后,组成的新的数组。

if(!Array.prototype.map){
	//rewrite map function
	Array.prototype.map = function(func,context){
		if(zylNewArray.isFunction(func)){
			var that = this,
				i=0,
				len=that.length;
			for(;i<len;i++){
				that[i] = func.call(context,that[i],i,that)
			}
			return that;
		}else{
			zylNewArray.NotFunctionErrorMessage();
		}
	}
}

例子:

var a = [1,2,3,4,5];
var b = a.map(function(item,index,array){
	return item * 2;
});
//b = [2,4,6,8,10]


这里是对数组的元素,都做了乘2的处理,并把乘2之后的数组值,构建一个新的数组返回。


forEach方法

没有返回值。

这个是这五种新方法中,唯一一个没有返回值的方法,它的作用类似for循环。

if(!Array.prototype.forEach){
	Array.prototype.forEach = function(func,context){
		if(zylNewArray.isFunction(func)){
			var that = this,
				i=0,
				len=that.length;
			for(;i<len;i++){
				func.call(context,that[i],i,that);
			}
		}else{
			zylNewArray.NotFunctionErrorMessage();
		}
	}
}


例子:

var a = [1,2,3,4,5];
a.forEach(function(item,index,array){
	console.log(item * 2);
});
这个就会打印出一串数据,2,4,6,8,10,可是呢,原数组也没变,又不返回值。


测试了下和for的性能,也都差不多,感觉这个函数怎么这么鸡肋呢,没有啥用啊。

也许是没有看到这个函数的精髓在哪里吧。。。



就这些吧,欢迎交流,欢迎指正!



1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:55850次
    • 积分:648
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:1篇
    • 译文:1篇
    • 评论:0条
    文章分类
    最新评论