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 相关文章推荐
细说浏览器特性检测(2)-通用事件检测
Nov 05 Javascript
单击复制文字兼容各浏览器的完美解决方案
Jul 04 Javascript
js自动生成对象的属性示例代码
Oct 28 Javascript
JS中的数组的sort方法使用示例
Jan 22 Javascript
通过$(this)使用jQuery包装后的方法或属性
May 18 Javascript
jQuery+easyui中的combobox实现下拉框特效
Feb 27 Javascript
js检测用户输入密码强度
Oct 22 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
Jan 18 Javascript
Es6 Generator函数详细解析
Feb 24 Javascript
JavaScript中将值转换为字符串的五种方法总结
Jun 06 Javascript
微信小程序实现张图片合成为一张并下载
Jul 16 Javascript
vue 实现单选框设置默认选中值
Nov 07 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
基于wordpress主题制作的具体实现步骤
2013/05/10 PHP
PHP修改session_id示例代码
2014/01/08 PHP
PHP入门之常量简介和系统常量
2014/05/12 PHP
ThinkPHP设置禁止百度等搜索引擎转码(简单实用)
2016/02/15 PHP
详解配置 Apache 服务器支持 PHP 文件的解析
2017/02/15 PHP
Extjs学习笔记之一 初识Extjs之MessageBox
2010/01/07 Javascript
javascript 程序库的比较(一)之DOM功能
2010/04/07 Javascript
屏蔽IE弹出&quot;您查看的网页正在试图关闭窗口,是否关闭此窗口&quot;的方法
2013/12/31 Javascript
微信小程序页面开发注意事项整理
2017/05/18 Javascript
JS 组件系列之Bootstrap Table的冻结列功能彻底解决高度问题
2017/06/30 Javascript
纯js实现的积木(div层)拖动功能示例
2017/07/19 Javascript
jquery实现回车键触发事件(实例讲解)
2017/11/21 jQuery
JS关于刷新页面的相关总结
2018/05/09 Javascript
JavaScript设计模式之装饰者模式定义与应用示例
2018/07/25 Javascript
iview在vue-cli3如何按需加载的方法
2018/10/31 Javascript
Node.js 进程平滑离场剖析小结
2019/01/24 Javascript
Vue使用Ref跨层级获取组件的步骤
2021/01/25 Vue.js
python fabric实现远程操作和部署示例
2014/03/25 Python
Python运算符重载用法实例分析
2015/06/01 Python
Laravel框架表单验证格式化输出的方法
2019/09/25 Python
python Jupyter运行时间实例过程解析
2019/12/13 Python
python 实现按对象传值
2019/12/26 Python
Python中url标签使用知识点总结
2020/01/16 Python
pytorch使用tensorboardX进行loss可视化实例
2020/02/24 Python
python与idea的集成的实现
2020/11/20 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
中国酒类在线零售网站:酒仙网
2016/08/20 全球购物
波兰香水和化妆品购物网站:Notino.pl
2017/11/07 全球购物
澳大利亚领先的内衣店:Bendon Lingerie澳大利亚
2020/05/15 全球购物
盛大笔试题
2016/11/05 面试题
高中生家长会演讲稿
2014/01/14 职场文书
三下乡活动方案
2014/01/31 职场文书
志愿者活动总结
2014/04/28 职场文书
就职演讲稿范文
2014/05/19 职场文书
个人剖析材料及整改措施
2014/10/07 职场文书
体检通知范文
2015/04/21 职场文书