利用apply和arguments复用方法

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var  nativeForEach = [].forEach
var  nativeMap = [].map
var  util = {
     each:  function  (obj, iterator, context) {
         if  (obj ==  null return
         if  (nativeForEach && obj.forEach === nativeForEach) {
           obj.forEach(iterator, context)
         else  if  ( obj.length === +obj.length ) {
             for  ( var  i = 0; i < obj.length; i++) {
                 if  (iterator.call(obj[i] || context, obj[i], i, obj) ===  true return
             }
         else  {
             for  ( var  in  obj) {
                 if  (iterator.call(obj[k] || context, obj[k], k, obj) ===  true return
             }
         }
     },
     map:  function (obj, iterator, context) {
         var  results = []
         if  (obj ==  null return  results
         if  (nativeMap && obj.map === nativeMap)  return  obj.map(iterator, context)    
         this .each(obj,  function (val, i, coll) {
             results[i] = iterator.call(context, val, i, coll)
         })
         return  results
     }
}

  

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

 

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

1
2
3
4
5
6
7
8
function  Collection(data) {
     this .data = data || []
     // some other property
     // this.xxx = yyy
}
Collection.prototype = {
     // some method
}

 

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

1
2
3
4
5
6
7
8
9
10
11
function  copyMethod(clazz, obj) {
     for  ( var  method  in  obj) {
         clazz.prototype[method] =  function () {
             var  args = [].slice.call(arguments)
             var  target =  this .data
             args.unshift(target)
             obj[method].apply(obj, args)
         }
     }
}
copyMethod(Collection, util)

 

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

1
2
3
4
5
6
7
8
9
10
11
12
var  coll =  new  Collection([10, 20, 30])
 
// 遍历
coll.each( function (k) {
     console.log(k)
})
 
// 操作
var  arr = coll.map( function (k) {
    return  k - 5
})
console.log(arr)  // 5, 15, 25

 

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

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Underscore methods that we want to implement on the Collection.
// 90% of the core usefulness of Backbone Collections is actually implemented
// right here:
var  methods = [ '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' ];
 
// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods,  function (method) {
   Collection.prototype[method] =  function () {
     var  args = slice.call(arguments);
     args.unshift( this .models);
     return  _[method].apply(_, args);
   };
});

 

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

1
2
3
4
5
6
7
8
9
10
var  modelMethods = [ 'keys' 'values' 'pairs' 'invert' 'pick' 'omit' ];
 
// Mix in each Underscore method as a proxy to `Model#attributes`.
_.each(modelMethods,  function (method) {
   Model.prototype[method] =  function () {
     var  args = slice.call(arguments);
     args.unshift( this .attributes);
     return  _[method].apply(_, args);
   };
});

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值