接下来几个篇章,都会解读 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. 【Spring】BeanFactory解析bean详解

    在该文中来讲讲Spring框架中BeanFactory解析bean的过程,该文之前在小编原文中有发表过,要看原文的可以直接点击原文查看,先来看一个在Spring中一个基本的bean定义与使用. pac ...

  2. webpack点滴记录

    有了webpack..(不借助gulp/grunt)代码压缩 图片base64,解析less/sass coffee css压缩,MD5加密都帮你做了..还支持按需加载..还有热替换 webpack常 ...

  3. MVC特性路由的提供机制

    回顾:传统路由是如何提供的? 我们知道最终匹配的路由数据是保存在RouteData中的,而RouteData通常又是封装在RequestContext中的,他们是在哪里被创建的呢?没错,回到了UrlR ...

  4. AVL树的旋转操作详解

    [0]README 0.0) 本文部分idea 转自:http://blog.csdn.net/collonn/article/details/20128205 0.1) 本文仅针对性地分析AVL树的 ...

  5. emmet(快速开发)的使用

    emmet可以帮助您快速编写HTML和CSS代码,从而加速Web前端开发. 比如<html>.<head>.<body>等,现在你只需要1秒钟就可以输入这些标签. ...

  6. 漫谈PHP代码规范

    前言 虽说PHP是世界上最好的语言,但是写出来的PHP代码却往往不是最美观的.究其原因,可能正式因为PHP简单易上手,适合快速迭代的特性,导致了我们沉浸在迅速完成需求迭代的窃喜中,却忘记了规范性.忽略 ...

  7. Oracle的基本学习(三)—函数

    一.字符函数   1.大小写控制函数 --lower:使字母变为小写-- --upper:使字母变为大写-- --initcap:使字符的第一个字母变为大写-- select lower('ABC') ...

  8. 使用Docker分分钟启动常用应用

    前言 Docker是目前比较火的一个概念,同时也是微服务中比较关键的一个容器化技术.但是,单从理论上好难看出Docker的优势,因此,我希望在这篇文章中提供一些Docker的使用示例,希望从实际应用上 ...

  9. js 模板引擎

    template = document.querySelector('#template').innerHTML, result = document.querySelector('.result') ...

  10. JAVA----类的继承1(extends)

    要学习类的继承,首先应当理解继承的含义: 来自新华词典的释义: ①依法承受(死者的遗产等):-权ㄧ-人. ②泛指把前人的作风.文化.知识等接受过来:-优良传统ㄧ-文化遗产. ③后人继续做前人遗留下来的 ...