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 相关文章推荐
Jquery中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
Oct 12 Javascript
深入学习jQuery Validate表单验证
Jan 18 Javascript
JavaScript实现Base64编码转换
Apr 23 Javascript
判断是否存在子节点的实现代码
May 18 Javascript
javascript url几种编码方式详解
Jun 06 Javascript
jQuery实现两个select控件的互移操作
Dec 22 Javascript
jQuery设置图片等比例缩小的方法
Apr 29 jQuery
微信小程序之裁剪图片成圆形的实现代码
Oct 11 Javascript
JQuery Ajax跨域调用和非跨域调用问题实例分析
Apr 16 jQuery
vue中实现Monaco Editor自定义提示功能
Jul 05 Javascript
VSCode搭建React Native环境
May 07 Javascript
vue 限制input只能输入正数的操作
Aug 05 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+APACHE实现用户论证的方法
2006/10/09 PHP
php学习 函数 课件
2008/06/15 PHP
php的declare控制符和ticks教程(附示例)
2014/03/21 PHP
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
2014/06/05 PHP
ThinkPHP3.2框架使用addAll()批量插入数据的方法
2017/03/16 PHP
如何让页面加载完成后执行js
2013/06/26 Javascript
jQuery实现预加载图片的方法
2015/03/17 Javascript
JavaScript的设计模式经典之建造者模式
2016/02/24 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
JavaScript必看小技巧(必看)
2016/06/07 Javascript
基于JSON格式数据的简单jQuery幻灯片插件(jquery-slider)
2016/08/10 Javascript
详解基于javascript实现的苹果系统底部菜单
2016/12/02 Javascript
jQuery实现全选、反选和不选功能
2017/08/16 jQuery
js input输入百分号保存数据库失败的解决方法
2018/05/26 Javascript
Vue框架里使用Swiper的方法示例
2018/09/20 Javascript
创建echart多个联动的示例代码
2018/11/23 Javascript
js中数组常用方法总结(推荐)
2019/04/09 Javascript
vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)
2019/04/12 Javascript
nodejs文件夹深层复制功能
2019/09/03 NodeJs
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
[01:57]DOTA2上海特锦赛小组赛解说单车采访花絮
2016/02/27 DOTA
python thread 并发且顺序运行示例
2009/04/09 Python
解读Python编程中的命名空间与作用域
2015/10/16 Python
用Python设计一个经典小游戏
2017/05/15 Python
Python实现注册、登录小程序功能
2018/09/21 Python
python pygame实现五子棋小游戏
2020/10/26 Python
python解析yaml文件过程详解
2019/08/30 Python
Anaconda+Pycharm环境下的PyTorch配置方法
2020/03/13 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
2020/12/31 Python
小学一年级学生评语
2014/04/22 职场文书
建筑院校毕业生求职信
2014/06/13 职场文书
寻找最美家庭活动方案
2014/08/20 职场文书
2014年部门工作总结
2014/11/12 职场文书
未婚证明格式
2015/06/15 职场文书
毕业典礼致辞
2015/07/29 职场文书
2016党员党课心得体会
2016/01/07 职场文书