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 switch case 另类写法
Mar 14 Javascript
分享27款非常棒的jQuery 表单插件
Mar 28 Javascript
JavaScript变量的作用域全解析
Aug 14 Javascript
jquery实现邮箱自动填充提示功能
Nov 17 Javascript
AngularJS延迟加载html template
Jul 27 Javascript
多种方式实现js图片预览
Dec 12 Javascript
fckeditor部署到weblogic出现xml无法读取及样式不能显示问题的解决方法
Mar 24 Javascript
JS实现商品筛选功能
Aug 19 Javascript
Node.js实现文件上传的示例
Jun 28 Javascript
vue 内置过滤器的使用总结(附加自定义过滤器)
Dec 11 Javascript
Vue实现数据请求拦截
Oct 23 Javascript
Vue作用域插槽实现方法及作用详解
Jul 08 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
回答PHPCHINA上的几个问题:URL映射
2007/02/14 PHP
使用cookie实现统计访问者登陆次数
2013/06/08 PHP
php四种基础算法代码实例
2013/10/29 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
2016/07/14 PHP
JAVASCRIPT下判断IE与FF的比较简单的方式
2008/10/17 Javascript
JQuery中的ready函数冲突的解决方法
2010/05/17 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
解析javascript 实用函数的使用详解
2013/05/10 Javascript
基于jQuery实现放大镜特效
2020/10/19 Javascript
JS实现的倒计时效果实例(2则实例)
2015/12/23 Javascript
javascript html5实现表单验证
2016/03/01 Javascript
js倒计时显示实例
2016/12/11 Javascript
用angular实现多选按钮的全选与反选实例代码
2017/05/23 Javascript
关于laydate.js加载laydate.css路径错误问题解决
2017/12/27 Javascript
Vue header组件开发详解
2018/01/26 Javascript
vue-cli 构建骨架屏的方法示例
2018/11/08 Javascript
js实现点击图片在屏幕中间弹出放大效果
2019/09/11 Javascript
详解Vue.js 作用域、slot用法(单个slot、具名slot)
2019/10/15 Javascript
原生js实现随机点名功能
2019/11/05 Javascript
python opencv旋转图像(保持图像不被裁减)
2018/07/26 Python
对Pyhon实现静态变量全局变量的方法详解
2019/01/11 Python
Python切片操作去除字符串首尾的空格
2019/04/22 Python
Django ORM 常用字段与不常用字段汇总
2019/08/09 Python
python实现异常信息堆栈输出到日志文件
2019/12/26 Python
eBay法国购物网站:eBay.fr
2017/10/21 全球购物
POP文化和音乐灵感的时尚:Hot Topic
2019/06/19 全球购物
非功能性需求都包括哪些方面
2013/10/29 面试题
出纳的岗位职责
2013/11/09 职场文书
《美丽的黄昏》教学反思
2014/02/28 职场文书
幽默自我介绍演讲稿
2014/08/21 职场文书
市场总监岗位职责
2015/02/11 职场文书
税务会计岗位职责
2015/04/02 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
通过T-SQL语句创建游标与实现数据库加解密功能
2022/03/16 SQL Server
在虚拟机中安装windows server 2008的图文教程
2022/06/28 Servers