jQuery 迭代器

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

    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');
})

 
上一篇:js模块化开发——require.js学习总结


下一篇:Kafka中的zookeeper-shell.sh