在 叶小钗 的博客中看到一段关于遍历的代码

    var ajQuery = {};

function dir(elem, dir, until) {
var matched = [],
truncate = until !== undefined;
while ((elem = elem[dir]) && elem.nodeType !== 9) {
if (elem.nodeType === 1) {
if (truncate) {
if (elem.nodeName.toLowerCase() == until || elem.className == until) {
break;
}
}
matched.push(elem);
}
}
return matched;
} // 迭代器
jQuery.each({
parent: function(elem) {
var parent = elem.parentNode;
return parent && parent.nodeType !== 11 ? parent : null;
},
parents: function(elem) {
return dir(elem, "parentNode");
},
parentsUntil: function(elem, until) {
return dir(elem, "parentNode", until);
}
}, function(name, fn) {
ajQuery[name] = function(until, selector) {
return fn(until, selector);
};
}); $("#test1").click(function() {
var item = $('.item-1');
alert(item.parent()[0])
alert(item.parents().length)
alert(item.parentsUntil('body').length)
}) $("#test2").click(function() {
var item = document.querySelectorAll('.item-1')[0]
alert(ajQuery.parent(item))
alert(ajQuery.parents(item).length)
alert(ajQuery.parentsUntil(item, 'body').length)
})

jQuery 中的each 不仅仅是用来遍历jQuery对象,还可以用来作为合并接口。

jQuery.each({
parent: function(elem) {},
parents: function(elem) {},
nextAll: function(elem) {},
prevAll: function(elem) {},
................
}, function(name, fn) {
  api[name] = function(until, selector){
  };
});

其中就利用了$.each(fn)的特性,jQuery 源码中 :

 each: function( obj, callback, args ){}

为obj 执行回调函数 callback。

里面的巧妙之处在于:

在为obj执行回调函数的时候,回调函数为新的对象 ajQuery{},绑定了新的属性(或方法)

function(name, fn) {
ajQuery[name] = function(until, selector) {
return fn(until, selector);
};
}

测试:

jQuery.each({
say: function(cont){
console.log(cont);
}
}, function(name, fn) {
ajQuery[name] = function(until, selector) {
// 传递fn参数
return fn(until, selector);
};
});

$("#test1").click(function() {
    ajQuery.say('oooooooo'); // oooooooo
})

 

所以根据这个推论,总结each的原理:

1. 遍历obj对象;

2. 为callback传参;

3. 为每个obj[i],绑定callback

模拟写了个版本:

    o = {};
test = {
fn1: function(){},
fn2: function(){},
getDom: function(dom, fn){
var t = document.getElementById(dom)
return t.onclick = function(){
fn()
}
},
each: function(c, fn){
for(k in c){
fn.call(c[k],k,c[k]);
}
return c;
}
} test.each({
say: function(cont){
console.log(cont)
},
walk: function(length){
console.log('walk '+length);
}
}, function(name, fn) {
o[name] = function(name){
return fn(name);
}
})

// 调用
test.getDom('btn', function(){
  o.say('aaaaa');
})

 

jQuery 迭代器的更多相关文章

  1. jQuery迭代器

    http://www.imooc.com/code/3417 迭代器 迭代器是一个框架的重要设计.我们经常需要提供一种方法顺序用来处理聚合对象中各个元素,而又不暴露该对象的内部,这也是设计模式中的迭代 ...

  2. javascript设计模式实践之迭代器--具有百叶窗切换图片效果的JQuery插件(一)

    类似于幻灯片的切换效果,有时需要在网页中完成一些图片的自动切换效果,比如广告,宣传,产品介绍之类的,那么单纯的切就没意思了,需要在切换的时候通过一些效果使得切换生动些. 比较常用之一的就是窗帘切换了. ...

  3. JQuery操作类数组的工具方法

    JQuery学习之操作类数组的工具方法 在很多时候,JQuery的$()函数都返回一个类似数据的JQuery对象,例如$('div')将返回div里面的所有div元素包装的JQuery对象.在这中情况 ...

  4. JQuery常用函数及功能小结

    1.文档加载完成执行函数$(document).ready(function(){  alert("开始了");});2.添加/删除CSS类$("#some-id&quo ...

  5. 解密jQuery内核 Sizzle引擎筛选器 - 位置伪类(一)

    本章开始分析过滤器,根据API的顺序来 主要涉及的知识点 jQuery的组成 pushStack方法的作用 sizzle伪类选择器 首页我们知道jQuery对象是一个数组对象 内部结构 jQuery的 ...

  6. javascript设计模式实践之模板方法--具有百叶窗切换图片效果的JQuery插件(二)

    在上一篇<javascript设计模式实践之迭代器--具有百叶窗切换图片效果的JQuery插件(一)>里,通过采用迭代器模式完成了各初始化函数的定义和调用. 接下来就要完成各个切换效果的编 ...

  7. js/jquery/html前端开发常用到代码片段

    1.IE条件注释 条件注释简介 IE中的条件注释(Conditional comments)对IE的版本和IE非IE有优秀的区分能力,是WEB设计中常用的hack方法.条件注释只能用于IE5以上,IE ...

  8. JQuery常用方法一览

    $(”p”).addClass(css中定义的样式类型); 给某个元素添加样式 $(”img”).attr({src:”test.jpg”,alt:”test Image”}); 给某个元素添加属性/ ...

  9. js设计模式总结-迭代器模式

    迭代器模式 要解决的问题 迭代器要解决的问题很简单很单纯,就是进行遍历操作. 实现原理 基本所有语言都实现了迭代器,javascript也不例外,如Array.prototype.forEach,fo ...

随机推荐

  1. hdu 5115 Dire Wolf(区间dp)

    Problem Description Dire wolves, also known as Dark wolves, are extraordinarily large and powerful w ...

  2. JAVA布局管理器

    JAVA的界面布局原理:由于Java是跨平台语言,使用绝对坐标显然会导致问题,即在不同平台.不同分辨率下的显示效果不一样.Java 为了实现跨平台的特性并且获得动态的布局效果,Java将容器内的全部组 ...

  3. 蓝桥杯D1

    整数因式分解的问题.了解了一下筛法计算素数的算法.之前都是直接跑的sqrt(n)... 上方的genPrime()即筛法.大致意思是开一个标识数组,通过循环,下标为合数的位置置为false. #inc ...

  4. Fast InvSqrt()(平方根倒数速算法)

    浮点数的平方根倒数常用于计算正规化矢量.3D图形程序需要使用正规化矢量来实现光照和投影效果,因此每秒都需要做上百万次平方根倒数运算,而在处理坐标转换与光源的专用硬件设备出现前,这些计算都由软件完成,计 ...

  5. leetcode Swap Nodes in Pairs python

    # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val = ...

  6. mysql 索引创建规则

    1.表的主键.外键必须有索引:2.数据量超过300的表应该有索引: 3.经常与其他表进行连接的表,在连接字段上应该建立索引: 4.经常出现在Where子句中的字段,特别是大表的字段,应该建立索引: 5 ...

  7. 超简单TAB切换

    <div class="tab-fbox2"> <ul class="title-list2 clearfix"> <li cla ...

  8. SQL Server MySQL 中的 in 与 null

    例子: create table t(x int,y int); insert into t(x,y) values(1,1),(2,2),(null,null); 查询一: select x,y f ...

  9. SQL Server 查看数据页面

    第一步: 找到表的第一页dbcc ind(db_name,table_name,-1); 例子. dbcc ind(studio,person,-1);# pageFID  是文件号   pagePI ...

  10. ubuntu下使用命令行创建一个android项目

    在ubuntu中配置好jdk和android_sdk环境后,可以通过命令行方式创建一个android工程. 具体命令如下: android create project --target <ta ...