javascript利用apply和arguments复用方法

首先,有个单例对象,它上面挂了很多静态工具方法。其中有一个是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 DOM元素尺寸和位置 - 2015-06-02 14:06:01

一 获取元素的CSS大小 1.通过style内联获取元素的大小 复制代码 代码如下: var box = document.getElementById('box'); // 获得元素; box.style.width; // 200px; box.style.height; // 200px; // PS:style获取只能取到行内style属性的CSS样式中的宽和高,如果有,则获取;如果没有则返回空; 2.通过计算获取元素的大小 复制代码 代码如下: var style = window.getCom
事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。 div id="outer" p id="inner"Click me!/p/div 上面的代码当中一个div元素当中有一个p子元素,如果两个元素都有一个click的处理函数,那么我们怎么才能知道哪一个函数会首先被触发呢? 为了解决这个问题微软和网景提出了两种几乎完全相反的概念。 事件冒泡 微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻为把一颗石头投入水中,泡泡会
一.摘要 本系列文章将带您进入jQuery的精彩世界, 其中有很多作者具体的使用经验和解决方案, 即使你会使用jQuery也能在阅读中发现些许秘籍. 开发人员一直痛疼做动画. 但是有了jQuery你会瞬间成为别人(那些不知道jQuery的人)眼里的动画高手! 本文将介绍jQuery的动画相关函数.原来做动画如此简单! 二.前言 本系列文章的实例都是针对某一个技术细节的, 因为我们要学习的是基础知识, 虽然总有人希望要复杂一些的应用示例, 但是我想还是让我们先把基础打牢, 有了扎实的基础凭借每个人的智慧一定

js中匿名函数的N种写法 - 2015-06-02 14:06:18

匿名函数没有实际名字,也没有指针,怎么执行滴? 其实大家可以看看小括号的意义就应该可以理解。小括号有返回值,也就是小括号内的函数或者表达式的返回值,所以说小括号内的function返回值等于小括号的返回值,不难理解 (function(){})()可以将没有名字的函数执行了把… 关于匿名函数写法,很发散~ 最常见的用法: 复制代码 代码如下: (function() { alert('water'); })(); 当然也可以带参数: 复制代码 代码如下: (function(o) { alert(o); }
本文实例分析了javascript定义变量时带var与不带var的区别。分享给大家供大家参考。具体分析如下: 直接看实例里说明: 复制代码 代码如下: script language="javascript" type="text/javascript" var abc=89;//带var,表示全局变量 function test(){ var abc=80;//在函数内部,如果不带var,表示使用函数外全局变量;带上var,表示新定义一个全局变量 } test(); window.alert(abc);
过滤器是用来更改修改数据,并且可以在表达式或使用管道符指令将其归入。以下是常用的过滤器的列表。 S.No.名称描述 1大写转换文本为大写文本。 2小写转换文本为小写文本。 3货币货币格式格式文本。 4过滤器过滤数组中它根据所提供的标准的一个子集。 5排序排序提供标准的基础数组。 大写过滤器 添加大写的过滤器使用管道符的表达式。在这里,添加了大写过滤器,全部用大写字母打印学生姓名。 Enter first name:input type="text" ng-model="student.firstName"
昨天晚上在IBM上看了一篇关于在Java开发人员对于JavaScript看法的文章,感受很深,发现作为一个Java开发人员应该要懂得而且还要熟练JavaScript的能力.毕竟现在的JavaScript已经非常强大了,在Jquery,Ext等插件的注入后.已经慢慢再次受到Java开发人员的青睐了. 下面因为项目需要,特地编写了一个生成随机数的方法,而且是不重复. 代码如下: Javascript代码 复制代码 代码如下: // 定义存放生成随机数的数组 var array=new Array(); // 循

jQuery AjaxQueue改进步骤 - 2015-06-02 14:06:16

假期里没事就想着改进下,改得地方不多,主要有以下三点: complete回调在jquery1.5以后可以是一个函数数组,按数组顺序调用。 如果前一个请求未返回,新的请求发出,那么撤销前一个请求,也就是新的请求“覆盖”原请求。 写成面向对象的形式,再用一个AjaxManage进行简单的管理。 代码如下,详细可看注释: 复制代码 代码如下: ;(function($) { // override:新的请求是否要覆盖之前的请求 function AjaxQueue(override) { this.overrid
本文实例讲述了js简单实现点击左右运动的方法。分享给大家供大家参考。具体分析如下: 这里可实现点击向右,方块向右移动,点击向左,方块向左移动的效果 可以用setInterval来实现过多长时间,div移动多长的距离来实现运动效果。 要点一:如果元素的左边距离小于目标距离,则是正向移动,否则是负向移动 if(run.offsetLeft target){speed = 2;}else{speed = -2;} 要点二:如果元素的左边距离等于目标距离,停止定时器,否则,元素的左边距离等于现在的左边距离加上速度

javascript模拟命名空间 - 2015-06-02 14:06:16

在 C++ 和 C# 中,命名空间用于尽可能地减少名称冲突。例如,在 .NET Framework 中,命名空间有助于将 Microsoft.Build.Task.Message 类与 System.Messaging.Message 区分开来。JavaScript 没有任何特定语言功能来支持命名空间,但很容易使用对象来模拟命名空间。如果要创建一个 JavaScript 库,则可以将它们包装在命名空间内,而不需要定义全局函数和类,如下所示: var MSDNMagNS = {};MSDNMagNS.Pet