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 相关文章推荐
document.open() 与 document.write()的区别
Aug 13 Javascript
理解JAVASCRIPT中hasOwnProperty()的作用
Jun 05 Javascript
js用正则表达式来验证表单(比较齐全的资源)
Nov 17 Javascript
JavaScript中的console.dir()函数介绍
Dec 29 Javascript
JS获取数组最大值、最小值及长度的方法
Nov 24 Javascript
jQuery快速实现商品数量加减的方法
Feb 06 Javascript
JS 实现随机验证码功能
Feb 15 Javascript
详解Angular2组件之间如何通信
Jun 22 Javascript
简单实现js上传文件功能
Aug 21 Javascript
vue文件树组件使用详解
Mar 29 Javascript
webpack实践之DLLPlugin 和 DLLReferencePlugin的使用教程
Jun 10 Javascript
深入理解 ES6中的 Reflect用法
Jul 18 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数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
php session和cookie使用说明
2010/04/07 PHP
PHP快速排序quicksort实例详解
2016/09/28 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
PHP函数积累总结
2019/03/19 PHP
微信公众平台开发教程⑥ 微信开发集成类的使用图文详解
2019/04/10 PHP
微信公众平台开发教程①获取用户Openid及个人信息图文详解
2019/04/10 PHP
JavaScript读取中文cookie时的乱码问题的解决方法
2009/10/14 Javascript
基于jQuery的模仿新浪微博时间的组件
2011/10/04 Javascript
商城常用滚动的焦点图效果代码简单实用
2013/03/28 Javascript
js中继承的几种用法总结(apply,call,prototype)
2013/12/26 Javascript
Node.js 异步编程之 Callback介绍(一)
2015/03/30 Javascript
javascript实现判断鼠标的状态
2015/07/10 Javascript
浅谈jQuery 选择器和dom操作
2016/06/07 Javascript
总结在前端排序中遇到的问题
2016/07/19 Javascript
angular分页指令操作
2017/01/09 Javascript
集合Bootstrap自定义confirm提示效果
2017/09/19 Javascript
JS路由跳转的简单实现代码
2017/09/21 Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
2017/09/30 Javascript
微信小程序支付之c#后台实现方法
2017/10/19 Javascript
利用Angular2 + Ionic3开发IOS应用实例教程
2018/01/15 Javascript
微信小程序之分享页面如何返回首页的示例
2018/03/28 Javascript
Electron + vue 打包桌面操作流程详解
2019/06/24 Javascript
小程序使用分包的示例代码
2020/03/23 Javascript
Python使用pygame模块编写俄罗斯方块游戏的代码实例
2015/12/08 Python
感知器基础原理及python实现过程详解
2019/09/30 Python
Django 解决新建表删除后无法重新创建等问题
2020/05/21 Python
python给视频添加背景音乐并改变音量的具体方法
2020/07/19 Python
Numpy实现卷积神经网络(CNN)的示例
2020/10/09 Python
css3圆角边框和边框阴影示例
2014/05/05 HTML / CSS
Bootstrap File Input文件上传组件
2020/12/01 HTML / CSS
什么是方法的重载
2013/06/24 面试题
党员自我评价分享
2013/12/13 职场文书
汉字听写大会观后感
2015/06/12 职场文书
巴黎圣母院读书笔记
2015/06/26 职场文书
MySQL count(*)统计总数问题汇总
2022/09/23 MySQL