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 相关文章推荐
jsTree树控件(基于jQuery, 超强悍)[推荐]
Sep 01 Javascript
javascript 通用简单的table选项卡实现
May 07 Javascript
jQuery EasyUI API 中文文档 - TreeGrid 树表格使用介绍
Nov 21 Javascript
Javascript图像处理—为矩阵添加常用方法
Dec 27 Javascript
js 针对html DOM元素操作等经验累积
Mar 11 Javascript
jQuery实现tag便签去重效果的方法
Jan 20 Javascript
Bootstrap导航条学习使用(一)
Feb 08 Javascript
vue 实现类似淘宝星级评分的示例
Mar 01 Javascript
在vue组件中使用axios的方法
Mar 16 Javascript
vue实现随机验证码功能的实例代码
Apr 30 Javascript
webpack4之如何编写loader的方法步骤
Jun 06 Javascript
JavaScript 实现页面滚动动画
Apr 24 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 MSSQL 存储过程的方法
2008/12/24 PHP
Smarty Foreach 使用说明
2010/03/23 PHP
PHP处理JSON字符串key缺少双引号的解决方法
2014/09/16 PHP
PHP代码维护,重构变困难的4种原因分析
2016/01/25 PHP
有关PHP 中 config.m4 的探索
2020/08/26 PHP
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
2010/10/20 Javascript
Jquery下:nth-child(an+b)的使用注意
2011/05/28 Javascript
javascript操作数组详解
2014/12/17 Javascript
jQuery实现的仿百度分页足迹效果代码
2015/10/30 Javascript
轻松实现javascript图片轮播特效
2016/01/13 Javascript
JavaScript的Backbone.js框架入门学习指引
2016/05/07 Javascript
Angularjs通过指令监听ng-repeat渲染完成后执行脚本的方法
2016/12/31 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
详解在vue-cli项目中安装node-sass
2017/06/21 Javascript
详解webpack介绍&amp;安装&amp;常用命令
2017/06/29 Javascript
关于ES6箭头函数中的this问题
2018/02/27 Javascript
AngularJS自定义过滤器用法经典实例总结
2018/05/17 Javascript
[03:04]2018年国际邀请赛典藏宝瓶&莱恩声望物品展示 片尾有彩蛋
2018/06/04 DOTA
Python实现单词拼写检查
2015/04/25 Python
Python使用正则表达式过滤或替换HTML标签的方法详解
2017/09/25 Python
详解python3中tkinter知识点
2018/06/21 Python
详解多线程Django程序耗尽数据库连接的问题
2018/10/08 Python
使用OpenCV实现仿射变换—旋转功能
2019/08/29 Python
用python给csv里的数据排序的具体代码
2020/07/17 Python
Python3爬虫里关于识别微博宫格验证码的知识点详解
2020/07/30 Python
python如何控制进程或者线程的个数
2020/10/16 Python
关于Python不换行输出和不换行输出end=““不显示的问题(亲测已解决)
2020/10/27 Python
html5 canvas 简单画板实现代码
2012/01/05 HTML / CSS
网易微博Web App用HTML5开发的过程介绍
2012/06/13 HTML / CSS
安全大检查实施方案
2014/02/22 职场文书
实现中国梦思想汇报2014
2014/09/13 职场文书
2014年实习班主任工作总结
2014/11/08 职场文书
高二英语教学反思
2016/03/03 职场文书
MySQL注入基础练习
2021/05/30 MySQL
Promise静态四兄弟实现示例详解
2022/07/07 Javascript
maven 解包依赖项中的文件的解决方法
2022/07/15 Java/Android