zl程序教程

您现在的位置是:首页 >  前端

当前栏目

javascript利用apply和arguments复用方法

JavaScript方法 利用 apply 复用 arguments
2023-06-13 09:15:12 时间

首先,有个单例对象,它上面挂了很多静态工具方法。其中有一个是each,用来遍历数组或对象。

复制代码代码如下:


varnativeForEach=[].forEach
varnativeMap=[].map
varutil={
   each:function(obj,iterator,context){
       if(obj==null)return
       if(nativeForEach&&obj.forEach===nativeForEach){
         obj.forEach(iterator,context)
       }elseif(obj.length===+obj.length){
           for(vari=0;i<obj.length;i++){
               if(iterator.call(obj[i]||context,obj[i],i,obj)===true)return
           }
       }else{
           for(varkinobj){
               if(iterator.call(obj[k]||context,obj[k],k,obj)===true)return
           }
       }
   },
   map:function(obj,iterator,context){
       varresults=[]
       if(obj==null)returnresults
       if(nativeMap&&obj.map===nativeMap)returnobj.map(iterator,context)     
       this.each(obj,function(val,i,coll){
           results[i]=iterator.call(context,val,i,coll)
       })
       returnresults
   }
}

还有诸如every、some等对集合(Array,Hash)操作的工具函数。使用时采用util.xx方式。

如果定义了一个集合类,这个类内部有集合数据。

复制代码代码如下:


functionCollection(data){
   this.data=data||[]
   //someotherproperty
   //this.xxx=yyy
}
Collection.prototype={
   //somemethod
}

可以很方便的把util上的方法拷贝到集合类上,如

复制代码代码如下:
functioncopyMethod(clazz,obj){
   for(varmethodinobj){
       clazz.prototype[method]=function(){
           varargs=[].slice.call(arguments)
           vartarget=this.data
           args.unshift(target)
           obj[method].apply(obj,args)
       }
   }
}
copyMethod(Collection,util)

这样拷贝后,Collection的实例就有了util上的方法,util操作的集合对象(第一个参数)就是Collection的this.data。如下直接可以遍历this.data了。

复制代码代码如下:
varcoll=newCollection([10,20,30]) 

//遍历
coll.each(function(k){
   console.log(k)
})

//操作
vararr=coll.map(function(k){
  returnk-5
})
console.log(arr)//5,15,25

这种模式在很多开源库中使用,比如jQuery,它的$.each/$.map很方便的拷贝到了$().each/$().map。

又如Backbone,它的_.each/_.map/_.every/_.chain(还有很多)都拷贝到了Collection的原型上。

复制代码代码如下:
//UnderscoremethodsthatwewanttoimplementontheCollection.
//90%ofthecoreusefulnessofBackboneCollectionsisactuallyimplemented
//righthere:
varmethods=["forEach","each","map","collect","reduce","foldl",
 "inject","reduceRight","foldr","find","detect","filter","select",
 "reject","every","all","some","any","include","contains","invoke",
 "max","min","toArray","size","first","head","take","initial","rest",
 "tail","drop","last","without","difference","indexOf","shuffle",
 "lastIndexOf","isEmpty","chain"];

//MixineachUnderscoremethodasaproxyto`Collection#models`.
_.each(methods,function(method){
 Collection.prototype[method]=function(){
   varargs=slice.call(arguments);
   args.unshift(this.models);
   return_[method].apply(_,args);
 };
});

又有,把_.keys/_.values/_.pairs/_.invert/_.pick等对对象操作的实用方法拷贝了Backbone.Model上(1.0新增)

复制代码代码如下:
varmodelMethods=["keys","values","pairs","invert","pick","omit"];

//MixineachUnderscoremethodasaproxyto`Model#attributes`.
_.each(modelMethods,function(method){
 Model.prototype[method]=function(){
   varargs=slice.call(arguments);
   args.unshift(this.attributes);
   return_[method].apply(_,args);
 };
});