接下来几个篇章,都会解读 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. instance 网卡是如何被拉起来的?- 每天5分钟玩转 OpenStack(172)

    instance 的网卡是如何被配置并拉起的?这是理解和用好 cloud-init 非常关键的一步.我们先讨论一个最简单基础的场景:镜像中没有安装 cloud-init. 此时 instance 启动 ...

  2. Java环境----JDK开发环境搭建及环境变量配置

    1.啥是jdk? jdk的是java development kit的缩写,意思是java程序开发的工具包. jdk的版本,一共有三种,标准版(j2se),企业版(j2ee),移动设备版(j2me). ...

  3. git常见操作和常见错误

    最近写了个博客demo,在上传至github时,居然报错了,刚开始学习代码上传,免不了遇到一些问题,报错信息如下: fatal: remote origin already exists. (致命错误 ...

  4. 文本挖掘预处理之TF-IDF

    在文本挖掘预处理之向量化与Hash Trick中我们讲到在文本挖掘的预处理中,向量化之后一般都伴随着TF-IDF的处理,那么什么是TF-IDF,为什么一般我们要加这一步预处理呢?这里就对TF-IDF的 ...

  5. Ecplise 中 加载JDBC 连接 Mysql 数据库读取数据

    准备工作 首先下载 JDBC 驱动,下载地址https://www.mysql.com/products/connector/ 将压缩包解压得到文件 mysql-connector-java-5.1. ...

  6. nginx反向代理的nginx.conf配置

    下面的配置是nginx.conf的示例 nginx反向代理 就是说把跨域的url通过本地代理的方式,变成同域的请求,如此来解决跨域问题 该配置下 通过http://localhost/html5/路径 ...

  7. 脚本语言:Xmas(二)

    本篇,来谈谈类型系统,以及部分与垃圾收集器相关的内容. 一.基本类型 Xmas的基本类型:Null.Boolean.Label.String.Ref.Function.Integer.Float.De ...

  8. 如何禁止火狐onblur时alert()产生类似选中的拖蓝效果

    输入框中onblur 然后alert();会产生 复制 选中的效果的效果( 拖蓝) onblur="aa()"function aa(){ alert("--" ...

  9. 手机QQ无法临时会话的解决方案

    手机网页发起临时会话:    <a href="mqqwpa://im/chat?chat_type=wpa&uin=3355135984&version=1& ...

  10. JavaScript中 DOM操作方法

    DM是(Document Object Model)的简称. 一.找元素 document.getElementById()    根据id选择器找,最多找一个: document.getElemen ...