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 入门基础学习
Mar 10 Javascript
Jvascript学习实践案例(开发常用)
Jun 25 Javascript
jquery实现文本框数量加减功能的例子分享
May 10 Javascript
js自定义鼠标右键的实现原理及源码
Jun 23 Javascript
JavaScript事件委托用法分析
Jan 24 Javascript
JS实现回到页面顶部动画效果的简单实例
May 24 Javascript
js判断空对象的实例(超简单)
Jul 26 Javascript
thinkphp标签实现bootsrtap轮播carousel实例代码
Feb 19 Javascript
详解JavaScript中的数组合并方法和对象合并方法
May 11 Javascript
微信小程序canvas拖拽、截图组件功能
Sep 04 Javascript
vue简单封装axios插件和接口的统一管理操作示例
Feb 02 Javascript
详解Vue数据驱动原理
Nov 17 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
五款常用mysql slow log分析工具的比较分析
2011/05/22 PHP
php购物车实现代码
2011/10/10 PHP
Windows下安装PHP单元测试环境PHPUnit图文教程
2014/10/24 PHP
完美解决在ThinkPHP控制器中命名空间的问题
2017/05/05 PHP
详细对比php中类继承和接口继承
2018/10/11 PHP
一段非常简单的让图片自动切换js代码
2006/11/10 Javascript
js给页面加style无效果的解决方法
2014/01/20 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
js正则表达式验证邮件地址
2015/11/12 Javascript
jquery弹出遮掩层效果【附实例代码】
2016/04/28 Javascript
JavaScript制作颜色反转小游戏
2016/09/25 Javascript
jQuery实现多张图片上传预览(不经过后端处理)
2017/04/29 jQuery
layui弹出层效果实现代码
2017/05/19 Javascript
js字符限制(字符截取) 一个中文汉字算两个字符
2017/09/12 Javascript
JS中图片压缩的方法小结
2017/11/14 Javascript
vue 不使用select实现下拉框功能(推荐)
2018/05/17 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
vue3 源码解读之 time slicing的使用方法
2019/10/31 Javascript
深入浅析golang zap 日志库使用(含文件切割、分级别存储和全局使用等)
2020/02/19 Javascript
微信小程序自定义navigationBar顶部导航栏适配所有机型(附完整案例)
2020/04/26 Javascript
node脚手架搭建服务器实现token验证的方法
2021/01/20 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
python脚本实现统计日志文件中的ip访问次数代码分享
2014/08/06 Python
python实现在IDLE中输入多行的方法
2018/04/19 Python
PyQt5图形界面播放音乐的实例
2019/06/17 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
python实现逻辑回归的示例
2020/10/09 Python
Python监听剪切板实现方法代码实例
2020/11/11 Python
帕克纽约:PARKER NY
2018/12/09 全球购物
英国探险旅游专家:Explore
2018/12/20 全球购物
聘用意向书范本
2014/04/01 职场文书
2014年五四青年节活动策划书
2014/04/22 职场文书
民事诉讼代理授权委托书
2014/10/11 职场文书
2015年青年志愿者协会工作总结
2015/04/27 职场文书
小学英语教学经验交流材料
2015/11/02 职场文书
Nginx性能优化之Gzip压缩设置详解(最大程度提高页面打开速度)
2022/02/12 Servers