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 相关文章推荐
解决FLASH需要点击激活的代码
Dec 20 Javascript
CLASS_CONFUSION JS混淆 全源码
Dec 12 Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
Nov 14 Javascript
javascript 函数声明与函数表达式的区别介绍
Oct 05 Javascript
浅谈javascript的分号的使用
May 12 Javascript
详解用原生JavaScript实现jQuery的某些简单功能
Dec 19 Javascript
微信端开发--登录小程序步骤
Jan 11 Javascript
validform表单验证的实现方法
Mar 08 Javascript
详解基于Vue的支持数据双向绑定的select组件
Sep 02 Javascript
基于node+vue实现简单的WebSocket聊天功能
Feb 01 Javascript
详解JavaScript 的执行机制
Sep 18 Javascript
基于JavaScript实现简单扫雷游戏
Jan 02 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
require(),include(),require_once()和include_once()的异同
2007/01/02 PHP
PHP的autoload自动加载机制使用说明
2010/12/28 PHP
PHP中用正则表达式清除字符串的空白
2011/01/17 PHP
php表单提交问题的解决方法
2011/04/12 PHP
js动画(animate)简单引擎代码示例
2012/12/04 Javascript
JavaScript异步编程:异步数据收集的具体方法
2013/08/19 Javascript
javascript实现文本域写入字符时限定字数
2014/02/12 Javascript
jQuery实现元素的插入
2017/02/27 Javascript
为Jquery EasyUI 组件加上清除功能的方法(详解)
2017/04/13 jQuery
前端构建工具之gulp的语法教程
2017/06/12 Javascript
在vue中使用jointjs的方法
2018/03/24 Javascript
Vue 使用计时器实现跑马灯效果的实例代码
2019/07/11 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
python使用TensorFlow进行图像处理的方法
2018/02/28 Python
实例讲解python中的序列化知识点
2018/10/08 Python
一文了解Python并发编程的工程实现方法
2019/05/31 Python
基于python框架Scrapy爬取自己的博客内容过程详解
2019/08/05 Python
解决在pycharm运行代码,调用CMD窗口的命令运行显示乱码问题
2019/08/23 Python
Pytorch之保存读取模型实例
2019/12/30 Python
python代码实现猜拳小游戏
2020/11/30 Python
CSS Grid布局教程之什么是网格布局
2014/12/30 HTML / CSS
CSS3.0实现霓虹灯按钮动画特效的示例代码
2021/01/12 HTML / CSS
土耳其时尚购物网站:Morhipo
2017/09/04 全球购物
洛杉矶健身中心女性专用运动服饰品牌:Marika
2018/05/09 全球购物
高校教师岗位职责
2014/03/18 职场文书
升旗仪式主持词
2014/03/19 职场文书
小组名称和口号
2014/06/09 职场文书
党的群众路线教育实践活动对照检查材料范文
2014/09/24 职场文书
给女朋友道歉的话大全
2015/01/20 职场文书
撤诉申请怎么写
2015/05/19 职场文书
老人与海读书笔记
2015/06/26 职场文书
幼儿园六一主持词
2015/06/30 职场文书
解决golang结构体tag编译错误的问题
2021/05/02 Golang
Java并发编程必备之Future机制
2021/06/30 Java/Android
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js
Mysql索引失效 数据库表中有索引还是查询很慢
2022/05/15 MySQL