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 相关文章推荐
html页面显示年月日时分秒和星期几的两种方式
Aug 20 Javascript
使用javascript实现简单的选项卡切换
Jan 09 Javascript
浅谈javascript实现八大排序
Apr 27 Javascript
jQuery解析json数据实例分析
Nov 24 Javascript
javascript实现查找数组中最大值方法汇总
Feb 13 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
Mar 02 Javascript
详解JavaScript中js对象与JSON格式字符串的相互转换
Feb 14 Javascript
详解vue表单验证组件 v-verify-plugin
Apr 19 Javascript
jQuery Validate表单验证插件实现代码
Jun 08 jQuery
bootstrap3中container与container_fluid外层容器的区别讲解
Dec 04 Javascript
vue-devtools的安装步骤
Apr 23 Javascript
JS实现小米轮播图
Sep 21 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/10/09 PHP
php汉字转拼音的示例
2014/02/27 PHP
Yii清理缓存的方法
2016/01/06 PHP
汇总PHPmailer群发Gmail的常见问题
2016/02/24 PHP
ZendFramework2连接数据库操作实例
2017/04/18 PHP
php格式文件打开的四种方法
2018/02/24 PHP
PHP 实现文件压缩解压操作的方法
2019/06/14 PHP
javascript入门基础之私有变量
2010/02/23 Javascript
javascript多种数据类型表格排序代码分析
2010/09/11 Javascript
9行javascript代码获取QQ群成员具体实现
2013/10/16 Javascript
用正则表达式替换图片地址img标签
2013/11/22 Javascript
JS实现方向键切换输入框焦点的方法
2015/08/19 Javascript
javascript实现可键盘控制的抽奖系统
2016/03/10 Javascript
Nodejs从有门道无门菜鸟起飞必看教程
2016/07/20 NodeJs
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
Select2.js下拉框使用小结
2016/10/24 Javascript
微信小程序 WXDropDownMenu组件详解及实例代码
2016/10/24 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
jQuery Form表单取值的方法
2017/01/11 Javascript
基于BootStrap实现简洁注册界面
2017/07/20 Javascript
Vue resource中的GET与POST请求的实例代码
2017/07/21 Javascript
完美解决iview 的select下拉框选项错位的问题
2018/03/02 Javascript
jQuery easyui datagird编辑行删除行功能的实现代码
2018/09/20 jQuery
详解Vue的组件中data选项为什么必须是函数
2020/08/17 Javascript
python实现带声音的摩斯码翻译实现方法
2015/05/20 Python
使用Python的Tornado框架实现一个Web端图书展示页面
2016/07/11 Python
python导出hive数据表的schema实例代码
2018/01/22 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
树莓派与PC端在局域网内运用python实现即时通讯
2019/06/22 Python
迪卡侬比利时官网:Decathlon比利时
2019/12/28 全球购物
PHP如何去执行一个SQL语句
2016/03/05 面试题
直接有效的自我评价
2014/01/11 职场文书
年度考核自我评价
2014/01/25 职场文书
科长竞争上岗演讲稿
2014/05/12 职场文书
写景作文评语集锦
2014/12/25 职场文书
团代会邀请函
2015/02/02 职场文书