javascript闭包应用

感谢《JavaScript王者归来》作者月影,之前对闭包一点都不懂,看过他的书后,终于懂一点了。以下的例子是创建一个集合,这个集合可以指定数据类型,也可以不指定。另外一个each方法很有意思。

/**
 * 生成一个泛型的List集合
 */
function ListClassFactory(type){
   
    var data=[];
   

    var ret = function(){
       
        this.append.apply(this,arguments);
       
    }
   
    ret.base =  Array;
   
    ret.prototype= new Object();
   
    ret.prototype.append = function(){
       
        for(var i=0; i< arguments.length; i++){
           
            var element = arguments[i];
           
            if(typeof type == 'undefined'){
                data.push(element);
                continue;
            }
           
            if(typeof(element) == type || (typeof(type)=='function' && element instanceof type)){
                data.push(element);
                continue;
            }
           
            throw new TypeError("you are about to add an unavailable type of element. The specified type is /'"+ type+"/'");
        }
    }
   
    ret.prototype.toArray =  function(){
        return this.subarr.apply(this , [0,data.length]);
    }

    ret.prototype.count = function(){
        return data.length;
    }
   
    ret.prototype.get = function(i){
        return data[i];
    }
   
    //最核心的方法,循环每个元素,作为函参的参数
    //如果函参运行的返回值为false,这个返回值就不添加到新的集合中去
    ret.prototype.each = function(closure){
       
        var newListClass = ListClassFactory(ret.type);
        var newret = new newListClass();
       
        if(typeof closure =='undefined')
            closure = function(x){return x;};
       
        for(var i=0; i<data.length; i++){
            var rval = closure.apply(this,[data[i]].concat(i));
            if(rval || rval === 0)
                newret.append(rval);
        }
       
        return newret;
    }
   
    //求是否所有元素都符合函参的要求
    ret.prototype.all = function(closure){
        //alert(this.count());
        return this.each.call(this,closure).count()==this.count();
    }
   
    //求是否其中一个元素符合函参的要求
    ret.prototype.any = function(closure){
        return this.each.call(this, closure).count() > 0;
    }
   
    //求是否含有指定元素
    ret.prototype.contain = function(el){
        return this.any.call(this,function(x){return x == el;});
    }
   
    //求元素下标
    ret.prototype.indexOf = function(el){
        var newList = this.each.call(this,function(x,i){
            if(x == el)
                return i;
            return false;
        });
       
        var firstElement = newList.get(0);
       
        return firstElement ? firstElement : -1 ;
    }

    //求子集
    ret.prototype.subarr = function(start,end){
        var newAry = [];
        for(var i=start; i<end; i++){
            newAry[i] = data[i];
        }
        return newAry;
    }
   
    return ret;
   
}



<html>
<head>
<title>js test</title>
<script type="text/javascript" src="ListClassFactory.js"></script>
<script>
<!--


function dwn(s){
  document.write(s+"<br/>");

}

function Student(name,age){
  this.name=name;
  this.age= age;
}
Student.prototype.toString=function(){
  return "my name is:"+this.name +"/rmy age is:"+this.age;
}

//创建数据类型的集合
var ListClass = ListClassFactory('number');
var list = new ListClass(1,2,3);
dwn(list.toArray());

//循环集合每个元素,各元素加自己所有位置下标
var newlist1 = list.each(function(x,i){return x+i;});
newlist1.append(9);
dwn (newlist1.toArray());

//测试是否每个元素都大于0
dwn (list.all(function(x){
    return x>0;
}));

//测试不传入函参的情况
dwn (list.all());

//测试是否其中一个元素值大于2
dwn (list.any(function(x){
    return x > 2;
}));

//测试是否有一个元素值为9
dwn (list.contain(9));

//测试元素值为3的下标
dwn (list.indexOf(3));

//测试求子集
dwn(list.subarr(0,2));


/*
//测试function类型,并混一个非function类型的元素。抛异常仍正常。
var ListClass = ListClassFactory(Student);
var listObj = new ListClass(new Student("1",1),1);
dwn(listObj.toArray());
*/

-->
</script>
</head>
<body>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/yyb_gz/article/details/6328945