代码改变世界

Core Javascript1.6的Array方法扩展

2009-07-30 01:20  BlueDream  阅读(677)  评论(0编辑  收藏  举报
在Core JavaScript1.6中Firefox 和 SpiderMonkey又扩展了新的Array方法.
由于IE等浏览器不支持这里就直接给出扩展方法让其兼容所有浏览器.
1.forEach (便利所有数组,并将数组以及元素,索引传入回调函数做处理)
var forEach = function(array, callback, thisObject){
    
if(array.forEach){
        array.forEach(callback, thisObject);
    }
else{
        
for (var i = 0, len = array.length; i < len; i++) { callback.call(thisObject, array[i], i, array); }
    }
}
说明:
第一个参数array: 调用该方法的数组.
第二个参数callback: 处理数组的方法默认传入3个参数.依次是array[i],i,array(即:数组元素,索引,整个数组)
第三个参数thisObject: 改变callback函数对象的指针为thisObject
说的比较抽象,下面看下代码就好理解了.
范例一:
要求给定一个数组,一次输出数组的元素和索引.
var arr = ["a", "b", "c", "d"];
forEach(arr, function(element, index, array){
    document.writeln("[" + index + "] is " + element + "
<br/>");
});
范例二:
以writeln的方法换行输出数组.主要说明thisObject的作用.
var testVar = "全局变量";
var writer = {
    sb: [],
    write: 
function(s){
        
this.sb.push(s);
    },
    writeIn: 
function(s){
        alert(
this.testVar); // 测试this指针
        this.write(s + "\n");
    },
    toString: 
function(){
        
return this.sb.join("");
    }
}

var arr = [259];
forEach(arr, writer.writeIn, writer
/* 如果去掉这个参数可以发现指针指向全局了 */);
alert(writer.toString())

2.filter(将数组传进回调函数,按照条件过滤并返回符合条件的数组)
var filter = function(array, callback, thisObject){
    
if(array.filter){
        
return array.filter(callback, thisObject);
    }
else {
        
var res = new Array();
        
for(var i = 0, len = array.length; i < len; i++){ callback.call(thisObject, array[i], i, array) && res.push(array[i]);}
        
return res;
    }
}
范例:
var arr = filter([1,2,3,12,34,23],function(element){ return (element > 10)}); // 将数组进行筛选,筛选条件为值大于10,然后返回新数组.
alert(arr);// 12,34,23

3.every(将数组传入回调函数,如果有一个元素不符合函数条件则直接返回false,如果全部符合条件,则返回true)
var every = function(array, callback, thisObject){
    
if(array.every){
        
return array.every(callback, thisObject);
    }
else {
        
for(var i = 0, len = array.length; i < len; i++){ 
            
if(!callback.call(thisObject, array[i], i, array))  return false;
        }
        
return true;
    }
}
范例:
var arr = [1,12,3,4];
var isBound = every(arr,function(element){ return (element < 10)}); // 将数组进行筛选,只要有一个不符合<10 则返回false;
alert(isBound); // 因为12 > 10 所以不符合条件返回false.顺便说下[]空数组返回true.原因很简单.

4.map(将数组传进回调函数,通过回调函数对数组做处理,返回处理后的新数组)
var map = function(array, callback, thisObject){
    
if(array.map){
        
return array.map(callback, thisObject);
    }
else {
        
var len = arr.length;
        
var res = new Array(len)
        
for(var i = 0; i < len; i++){ res[i]=callback.call(thisObject, array[i], i, array);}
        
return res;
    }
}
范例:
var arr = [1,12,3,4];
var newarr = map(arr,function(element){ return (element * 10)}); // 将数组每个元素*10并返回新数组;
alert(newarr); // [10,120,30,40]

5.some(与every正好相反,将数组传进回调函数,只要有一个元素符合条件就为true.只有全部不满足条件为false)
var some = function(array, callback, thisObject){
    
if(array.some){
        
return array.some(callback, thisObject);
    }
else {
        
for(var i = 0, len = array.length; i < len; i++){ 
            
if(callback.call(thisObject, array[i], i, array))  return true;
        }
        
return false;
    }
}
范例:
var arr = [1,12,3,4];
var isBound = some(arr,function(element){ return (element > 10)}); // 只要有一个满足条件就返回true
alert(isBound);// 由于12>10满足条件所以true;只有全部都不符合返回false.如[1,2,3,4]

扩展属性还有indexOf和lastIndexOf因为比较简单就不进行扩展了.由于自己使用,所以对临界条件没进行判断.望指正.

这里再追加一个结合好的扩展就是函数般调用正则表达式.
原文
http://blog.stevenlevithan.com/archives/regular-expressions-as-functions
这里是FF下的一个非标准扩展.咱们自己可以给做下跨浏览器的扩展.
RegExp.prototype.call = function (context, str) {       
        
return this.exec(str);
};
RegExp.prototype.apply 
= function (context, args) { 
        
return this.exec(args[0]);
};
这样就会使exec函数使用起来方便的多..比如咱们结合上面的filter扩展可以这么做:
<script type="text/javascript">
<!--
RegExp.prototype.call 
= function (context, str) {       
        
return this.exec(str);
};
RegExp.prototype.apply 
= function (context, args) { 
        
return this.exec(args[0]);
};

var filter = function(array, callback, thisObject){
    
if(array.filter){
        
return array.filter(callback, thisObject);
    }
else {
        
var res = new Array();
        
for(var i = 0, len = array.length; i < len; i++){ callback.call(thisObject, array[i], i, array) && res.push(array[i]);}
        
return res;
    }
}

alert(filter([
"a","b","ab","ba"],/^a/)); // 这样callback传入的是正则对象.当 callback.call便调用了exec进行验证.所以很方便
alert(filter(["1",1,0,"a",3.0,256],/^[1-9]\d*/));
//-->
</script>
其余的扩展大家可以自行挖掘...