javascript利用apply和arguments复用方法


Posted in Javascript onNovember 25, 2013

首先,有个单例对象,它上面挂了很多静态工具方法。其中有一个是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); 
  }; 
});
Javascript 相关文章推荐
javascript 客户端验证上传图片的大小(兼容IE和火狐)
Aug 15 Javascript
全面兼容的javascript时间格式化函数(比较实用)
May 14 Javascript
jquery插件NProgress.js制作网页加载进度条
Jun 05 Javascript
JavaScript中对JSON对象的基本操作示例
May 21 Javascript
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
Mar 06 Javascript
xmlplus组件设计系列之下拉刷新(PullRefresh)(6)
May 03 Javascript
Mongoose中document与object的区别示例详解
Sep 18 Javascript
原生JS控制多个滚动条同步跟随滚动效果
Dec 22 Javascript
NestJs 静态目录配置详解
Mar 12 Javascript
JS实现指定区域的全屏显示功能示例
Apr 25 Javascript
使用layui 的layedit定义自己的toolbar方法
Sep 18 Javascript
用JS实现选项卡
Mar 23 Javascript
javascript模拟实现C# String.format函数功能代码
Nov 25 #Javascript
js给onclick赋值传参数的两种方法
Nov 25 #Javascript
自己动手实现jQuery Callbacks完整功能代码详解
Nov 25 #Javascript
写JQuery插件的基本知识
Nov 25 #Javascript
JavaScript动态操作表格实例(添加,删除行,列及单元格)
Nov 25 #Javascript
用javascript删除当前行,添加行(示例代码)
Nov 25 #Javascript
如何通过javascript操作web控件的自定义属性
Nov 25 #Javascript
You might like
php在页面中调用fckeditor编辑器的方法
2011/06/10 PHP
Linux+Nginx+MySQL下配置论坛程序Discuz的基本教程
2015/12/23 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
Laravel5.1自定义500错误页面示例
2016/10/09 PHP
thinkphp jquery实现图片上传和预览效果
2020/07/22 PHP
onpropertypchange
2006/07/01 Javascript
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
js压缩工具 yuicompressor 使用教程
2010/03/31 Javascript
JavaScript小技巧 2.5 则
2010/09/12 Javascript
使用JavaScript修改浏览器URL地址栏的实现代码
2013/10/21 Javascript
jquery幻灯片插件bxslider样式改进实例
2014/10/15 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
jQuery平滑旋转幻灯片特效代码分享
2015/09/07 Javascript
详解JavaScript UTC时间转换方法
2016/01/07 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
Websocket协议详解及简单实例代码
2016/12/12 Javascript
spirngmvc js传递复杂json参数到controller的实例
2018/03/29 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
[08:44]DOTA2发布会群星聚首 我们都是刀塔人
2014/03/21 DOTA
使用python检测主机存活端口及检查存活主机
2015/10/12 Python
编写Python爬虫抓取暴走漫画上gif图片的实例分享
2016/04/20 Python
python shell根据ip获取主机名代码示例
2017/11/25 Python
PyQt5 加载图片和文本文件的实例
2019/06/14 Python
Python StringIO如何在内存中读写str
2020/01/07 Python
新加坡网上化妆品店:Best Buy World
2018/05/18 全球购物
Tiqets英国:智能手机上的文化和娱乐门票
2019/07/10 全球购物
策划主管的工作职责
2013/11/24 职场文书
校园安全检查制度
2014/02/03 职场文书
社区学习雷锋活动总结
2014/04/25 职场文书
优秀员工评优方案
2014/06/13 职场文书
活动总结模板大全
2015/05/11 职场文书
家庭暴力离婚起诉书
2015/05/18 职场文书
2016元旦晚会主持人开场白和结束语
2015/12/03 职场文书
Python Parser的用法
2021/05/12 Python
分析Java中Map的遍历性能问题
2021/06/26 Java/Android
Java获取字符串编码格式实现思路
2022/09/23 Java/Android