接下来几个篇章,都会解读 zepto 中的跟 dom 相关的方法,也即源码 $.fn 对象中的方法。

读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto

源码版本

本文阅读的源码为 zepto1.2.0

.forEach()

forEach: emptyArray.forEach

因为 zepto 的 dom 集合是类数组,所以这里只是简单地复制了数组的 forEach 方法。

具体的 forEach 的用法见文档:Array.prototype.forEach()

.reduce()

reduce: emptyArray.reduce

简单地复制了数组的 reduce 方法。

具体的 reduce 的用法见文档:Array.prototype.reduce()

.push()

push: emptyArray.push

简单地复制了数组的 push 方法。

具体的 push 的用法见文档:Array.prototype.push()

.sort()

sort: emptyArray.sort

简单地复制了数组的 sort 方法。

具体的 sort 的用法见文档:Array.prototype.sort()

.splice()

splice: emptyArray.splice

简单地复制了数组的 splice 方法。

具体的 splice 的用法见文档:Array.prototype.splice()

.indexOf()

indexOf: emptyArray.indexOf

简单地复制了数组的 indexOf 方法。

具体的 indexOf 的用法见文档:Array.prototype.indexOf()

.get()

get: function(idx) {
return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
},

这个方法用来获取指定索引值的元素。

不传参(idx === undefined)时,不传参调用数组的 slice 方法,将集合中的所有元素返回。

当传递的参数大于或等于零(idx)时,返回相应索引值的元素 this[idx] ,如果为负数,则倒数返回this.[idx + this.length]

例如 $('li').get(-1) 返回的是倒数第1个元素,也即最后一个元素

.toArray()

toArray: function() { return this.get() }

toArray 方法是将元素的类数组变成纯数组。toArray 内部不传参调用 get 方法,上面已经分析了,当不传参数时,get 方法调用的是数组方法 slice, 返回的自然就是纯数组了。

.size()

size: function() {
return this.length
}

size 方法返回的是集合中的 length 属性,也即集合中元素的个数。

.concat()

concat: function() {
var i, value, args = []
for (i = 0; i < arguments.length; i++) {
value = arguments[i]
args[i] = zepto.isZ(value) ? value.toArray() : value
}
return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)
},

数组中也有对应的 concat 方法,为什么不能像上面的方法那样直接调用呢?

这是因为 $.fn 其实是一个类数组对象,并不是真正的数组,如果直接调用 concat 会直接把整个 $.fn 当成数组的一个 item 合并到数组中。

for (i = 0; i < arguments.length; i++) {
value = arguments[i]
args[i] = zepto.isZ(value) ? value.toArray() : value
}

这段是对每个参数进行判断,如果参数是 zepto 的集合(zepto.isZ(value)),就先调用 toArray 方法,转换成纯数组。

return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)

这段同样对 this 进行了判断,如果为 zepto 集合,也先转换成数组。所以调用 concat 后返回的是纯数组,不再是 zepto 集合。

.map()

map: function(fn) {
return $($.map(this, function(el, i) { return fn.call(el, i, el) }))
}

map 方法的内部调用的是 zepto 的工具函数 $.map ,这在之前已经在《读Zepto源码之工具函数》做过了分析。

return fn.call(el, i, el)

map 方法对回调也做了包装,call 的第一个参数为 el ,因此可以在 map 的回调中通过 this 来拿到每个元素。

map 方法对 $.map 返回的数组调用了 $() 方法,将返回的数组再次包装成 zepto 对象,因此调用 map 方法后得到的数组,同样具有 zepto 集合中的方法。

.slice()

slice: function() {
return $(slice.apply(this, arguments))
}

slice 同样没有直接用数组的原生方法,也像 map 方法一样,将返回的数组再次包装成 zepto 对象。

.each()

each: function(callback) {
emptyArray.every.call(this, function(el, idx) {
return callback.call(el, idx, el) !== false
})
return this
},

zeptoeach 方法比较巧妙,在方法内部,调用的其实是数组的 every 方法,every 遇到 false 时就会中止遍历,zepto 也正是利用 every 这种特性,让 each 方法也具有了中止遍历的能力,当 callback 返回的值为布尔值 false 时,中止遍历,注意这里用了 !==,因为 callback 如果没有返回值时,得到的值会是 undefined ,这种情况是需要排除的。

同样,each 的回调中也是可以用 this 拿到每个元素的。

注意,each 方法最后返回的是 this, 所以在 each 调用完后,还可以继续调用 集合中的其他方法,这就是 zepto 的链式调用,这个跟 map 方法中返回 zepto 集合的原理差不多,只不过 each 返回的是跟原来一样的集合,map 方法返回的是映射后的集合。

.add()

add: function(selector, context) {
return $(uniq(this.concat($(selector, context))))
}

add 可以传递两个参数,selectorcontext ,即选择器和上下文。

add 调用 $(selector, context) 来获取符合条件的集合元素,这在上篇文章《读Zepto源码之神奇的$》已经有详细的论述。

然后调用 concat 方法来合并两个集合,用内部方法 uniq 来过滤掉重复的项,uniq 方法在《读Zepto源码之内部方法》已经有论述。最后也是返回一个 zepto 集合。

系列文章

  1. 读Zepto源码之代码结构
  2. 读 Zepto 源码之内部方法
  3. 读Zepto源码之工具函数
  4. 读Zepto源码之神奇的$

参考

License

作者:对角另一面

读Zepto源码之集合操作的更多相关文章

  1. 读 Zepto 源码之集合元素查找

    这篇依然是跟 dom 相关的方法,侧重点是跟集合元素查找相关的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zept ...

  2. 读Zepto源码之样式操作

    这篇依然是跟 dom 相关的方法,侧重点是操作样式的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zepto1.2. ...

  3. 读Zepto源码之属性操作

    这篇依然是跟 dom 相关的方法,侧重点是操作属性的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zepto1.2. ...

  4. 读Zepto源码之操作DOM

    这篇依然是跟 dom 相关的方法,侧重点是操作 dom 的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zepto1 ...

  5. 读Zepto源码之Event模块

    Event 模块是 Zepto 必备的模块之一,由于对 Event Api 不太熟,Event 对象也比较复杂,所以乍一看 Event 模块的源码,有点懵,细看下去,其实也不太复杂. 读Zepto源码 ...

  6. 读Zepto源码之Callbacks模块

    Callbacks 模块并不是必备的模块,其作用是管理回调函数,为 Defferred 模块提供支持,Defferred 模块又为 Ajax 模块的 promise 风格提供支持,接下来很快就会分析到 ...

  7. 读Zepto源码之Deferred模块

    Deferred 模块也不是必备的模块,但是 ajax 模块中,要用到 promise 风格,必需引入 Deferred 模块.Deferred 也用到了上一篇文章<读Zepto源码之Callb ...

  8. 读Zepto源码之Ajax模块

    Ajax 模块也是经常会用到的模块,Ajax 模块中包含了 jsonp 的现实,和 XMLHttpRequest 的封装. 读 Zepto 源码系列文章已经放到了github上,欢迎star: rea ...

  9. 读Zepto源码之Selector模块

    Selector 模块是对 Zepto 选择器的扩展,使得 Zepto 选择器也可以支持部分 CSS3 选择器和 eq 等 Zepto 定义的选择器. 在阅读本篇文章之前,最好先阅读<读Zept ...

随机推荐

  1. Java内存泄露实例

  2. 性能测试分享:MYSQL死锁

    poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-845052 ...

  3. Android 微信第三方登录

    步骤一 微信开发者平台 我开始的解决思路是,去微信开发者平台看API文档. 这个API文档的主要意思呢,有三点: 1.你得下载这几样东西(下载链接),一个是他的范例代码,一个是他的签名生成工具. 2. ...

  4. php运算时默认的类型转换

    php属于弱类型语言,使用数据时无需指定其数据类型.对于学C语言入门的我,刚刚接触时感觉很神奇,但是随之而来的也有烦恼. 总结一下php中默认的类型转换,按照运算符类型,只总结能够自动做类型转换的运算 ...

  5. 1145: 零起点学算法52——数组中删数II

    1145: 零起点学算法52--数组中删数II Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 293 ...

  6. BZOJ2818 与 BZOJ2301【euler,线性筛,莫比乌斯】

    题目大意: 给一个范围[1,n],从中找出两个数x,y,使得gcd(x,y)为质数,问有多少对(x,y有序) 解法: 不难,欧拉函数练手题,可以定义集合P ={x|x为素数},那么我们枚举gcd(x, ...

  7. zepto.js介绍

    是一个阉割版的jQuery zepto不支持jQuery过于复杂的选择器,比如:first :last :eq zepto如果要用动画必须再次引包 zepto能将css3中transition支持的动 ...

  8. (转载)Google的PageRank算法

    本文由张洋(敲代码的张洋)投稿于伯乐在线. 本文转载于:http://blog.jobbole.com/23286/ 很早就对Google的PageRank算法很感兴趣,但一直没有深究,只有个轮廓性的 ...

  9. 揭秘Kafka高性能架构之道 - Kafka设计解析(六)

    原创文章,同步首发自作者个人博客.转载请务必在文章开头处以超链接形式注明出处http://www.jasongj.com/kafka/high_throughput/ 摘要 上一篇文章<Kafk ...

  10. 2017百度web前端实习生在线笔试题

    代码: import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner s ...