Heim  >  Artikel  >  Web-Frontend  >  javascript利用apply和arguments复用方法_javascript技巧

javascript利用apply和arguments复用方法_javascript技巧

WBOY
WBOYOriginal
2016-05-16 17:12:301068Durchsuche

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

复制代码 代码如下:

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                 if (iterator.call(obj[i] || context, obj[i], i, obj) === true) return
            }
        } else {
            for (var k 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方式。

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

复制代码 代码如下:

function Collection(data) {
    this.data = data || []
    // some other property
    // this.xxx = yyy
}
Collection.prototype = {
    // some method
}

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

复制代码 代码如下:

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了。

复制代码 代码如下:

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的原型上。

复制代码 代码如下:

// 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新增)

复制代码 代码如下:

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);
  };
});

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn