首先,有个单例对象,它上面挂了很多静态工具方法。其中有一个是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 < obj.length; 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);
};
});

  

利用apply和arguments复用方法的更多相关文章

  1. js基础篇——call/apply、arguments、undefined/null

    a.call和apply方法详解 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象 ...

  2. JavaScript的apply()方法和call()方法

    1 <script type="text/javascript"> 2 /*定义一个人类*/ 3 function Person(name,age) 4 { 5 thi ...

  3. 解析 this.initialize.apply(this, arguments)

    一. 起因 那天用到prototype.js于是打开看看,才看几行就满头雾水,原因是对js的面向对象不是很熟悉,于是百度+google了一把,最后终于算小有收获,写此纪念一下^_^. prototyp ...

  4. jquery 中 fn.apply(this, arguments)是什么函数?有什么作用?能举个例子吗

    function Person(name){ this.name=name; this.sayname=function (){ alert(this.name); } } function Stud ...

  5. apply方法和call方法。函数属性与方法。

    每个函数都有length属性哥prototype属性. length属性表示的是函数接入参数的个数 在es引用类型语言中,prototype是保存它们所有实例方法的真正所在.换句话来说,类似于toSt ...

  6. 【JavaScript】call和apply区别及使用方法

    一.方法的定义call方法: 语法:fun.call(thisArg[, arg1[, arg2[, ...]]])定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来 ...

  7. apply方法和call方法的详解2

    1.apply和call的区别在哪里 2.什么情况下用apply,什么情况下用call 3.apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和call的定 ...

  8. apply()和call()的方法

    apply()和call()的方法的区别 参考文档https://www.cnblogs.com/lengyuehuahun/p/5643625.html 一直都没太明白apply()与call()的 ...

  9. call和apply用途与使用方法

    当你看代码时,经常会看到以下情形:(在这个博客里面,参数context是执行上下文的意思,params是参数的意思) Object.prototype.toString.call(context, p ...

随机推荐

  1. R语言XML格式数据导入与处理

    数据解析 XML是一种可扩展标记语言,它被设计用来传输和存储数据.XML是各种应用程序之间进行数据传输的最常用的工具.它与Access,Oracle和SQL Server等数据库不同,数据库提供了更强 ...

  2. Hyhyhy – 专业的 HTML5 演示文稿工具

    Hyhyhy 是创建好看的 HTML5 演示文档的工具.它具备很多的特点:支持 Markdown,嵌套幻灯片,数学排版,兼容性,语法高亮,使用 Javascript API ,方便的骨架.它支持 Fi ...

  3. Riot - 比 Facebook React 更轻量的 UI 库

    Riot 是一个类似 Facebook React 的用户界面库,只有3.5KB,非常轻量.支持IE8+浏览器的自定义标签,虚拟 DOM,语法简洁.Riot 给前端开发人员提供了除 React 和 P ...

  4. Onsen UI – 新鲜出炉的 PhoneGap 界面框架

    Onsen UI 是一个基于元素自定义的 HTML5 UI 框架,用于构建你的移动前端.这个一个基于 Web 组件的概念的框架,让构建应用程序变得更加轻松.Onsen UI 专门针对 PhoneGap ...

  5. [js开源组件开发]数字或金额千分位格式化组件

    数字或金额千分位格式化组件 这次距离上一个组件<[js开源组件开发]table表格组件>时隔了一个月,由于最近的项目比较坑,刚挖完坑,所以来总结性提出来几个组件弥补这次的空缺,首先是金额和 ...

  6. NavigationBar隐藏后,返回时表现不完美

    是这样的,app首页头部可能要自定义,所以选择把NavigationBar隐藏,所以在viewWillAppear时这样写: self.navigationController?.setNavigat ...

  7. web前端命名规范

    在做web项目的时候,命名的规范是很重要.初学者一般急于求成对命名规范没有概念,觉得花时间这些还不如多看几遍框架.其实在我看来,一个良好的命名习惯是很重要的.下面就来介绍一下我总结的命名规范: (1) ...

  8. SAP中查询用户操作日志的事务码

    事务码:STAD 注意:查询的时间跨度范围不要太大,否则会很慢! 事务码:ST03N 工作负载和性能统计

  9. 什么时候用Application的Context,什么时候用Activity的Context

    单例模式用application的context 如果我们在Activity A中或者其他地方使用Foo.getInstance()时,我们总是会顺手写一个『this』或者『mContext』(这个变 ...

  10. Android启动模式launchMode

    在Android里,有4种Activity的启动模式并分别介绍下: standard singleTop singleTask singleInstance AndroidManifest.xml配置 ...