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 相关文章推荐
JS 控制CSS样式表
Aug 20 Javascript
javascript的onchange事件与jQuery的change()方法比较
Sep 28 Javascript
js鼠标左右键 键盘值小结
Jun 11 Javascript
jQuery dialog 异步调用ashx,webservice数据的代码
Aug 03 Javascript
js获取浏览器的可视区域尺寸的实现代码
Nov 30 Javascript
跟我学习javascript创建对象(类)的8种方法
Nov 20 Javascript
jQuery之动画ajax事件(实例讲解)
Jul 18 jQuery
基于vue实现网站前台的权限管理(前后端分离实践)
Jan 13 Javascript
解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)
Jul 26 Javascript
node链接mongodb数据库的方法详解【阿里云服务器环境ubuntu】
Mar 07 Javascript
vue elementui el-form rules动态验证的实例代码详解
May 23 Javascript
Vue实战教程之仿肯德基宅急送App
Jul 19 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后台多用户权限组思路与实现程序代码分享
2012/02/13 PHP
php递归创建和删除文件夹的代码小结
2012/04/13 PHP
php截取后台登陆密码的代码
2012/05/05 PHP
win7下memCache的安装过程(具体操作步骤)
2013/06/28 PHP
php判断两个日期之间相差多少个月份的方法
2015/06/18 PHP
Ajax+PHP实现的删除数据功能示例
2019/02/12 PHP
php计数排序算法的实现代码(附四个实例代码)
2020/03/31 PHP
PHP 对象继承原理与简单用法示例
2020/04/21 PHP
一个多次搜索+多次传值的解决方案
2007/01/20 Javascript
js 鼠标点击事件及其它捕获
2009/06/04 Javascript
js判断IE6/IE7/FF的代码[XMLHttpRequest]
2011/02/16 Javascript
js 使FORM表单的所有元素不可编辑的示例代码
2013/10/17 Javascript
JS实时弹出新消息提示框并有提示音响起的实现代码
2016/04/20 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
微信小程序实现滑动删除效果
2017/05/19 Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
2018/04/05 Javascript
最适应的vue.js的form提交涉及多种插件【推荐】
2018/08/27 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
2020/10/28 Javascript
Python代码解决RenderView窗口not found问题
2016/08/28 Python
python实现12306火车票查询器
2017/04/20 Python
Python+Pandas 获取数据库并加入DataFrame的实例
2018/07/25 Python
Django 大文件下载实现过程解析
2019/08/01 Python
Python实现企业微信机器人每天定时发消息实例
2020/02/25 Python
python 如何将office文件转换为PDF
2020/09/22 Python
纯css3实现的动画按钮的实例教程
2014/11/17 HTML / CSS
MANGO官方网站:西班牙芒果服装品牌
2017/01/15 全球购物
What's the difference between deep copy and shallow copy? (深拷贝与浅拷贝有什么区别)
2015/11/10 面试题
优秀团员自我评价范文
2014/04/23 职场文书
水利水电建筑施工应届生求职信
2014/07/04 职场文书
2014年学校禁毒工作总结
2014/12/23 职场文书
校友回访母校寄语
2015/02/26 职场文书
大学生入党自我鉴定范文
2019/06/21 职场文书
python爬虫之爬取笔趣阁小说
2021/04/22 Python
CSS3新特性详解(五):多列columns column-count和flex布局
2021/04/30 HTML / CSS
python 使用Tensorflow训练BP神经网络实现鸢尾花分类
2021/05/12 Python
CSS Transition通过改变Height实现展开收起元素
2021/08/07 HTML / CSS