【Zepto】Web前端开发框架源码_集合方法

前端数据库开发框架|前端开发项目具体步骤加源码|移动前端开发源码

#size
既然是类数组,有length属性,看此集合的大小。
其实现应该说是最简单的:
[quote]$.fn.size = function() {
return this.length;
};[/quote]
其中$.fn,应该没人不知道吧,
$是个函数,$.fn是$.prototype。

#toArray
把$实例变成真正数组。
可以以如下的方式实现:
[quote]$.fn.toArray = function() {
return [].slice.call(this);
};[/quote]
当然了其源码不是这么做的,内部调用了get方法:
[quote]$.fn.toArray = function() {
return this.get();
};[/quote]

#get
我们可以使用$(‘div’)[0]获取第一个元素,那么也可以使用$(‘div’).get(0)来做。
其实现如下:
[quote]$.fn.get = function(idx) {
return idx === undefined ? [].slice.call(this) : this[idx >= 0 ? idx : idx + this.length];
};[/quote]
如果没传参数,那么返回整个数组,也就相当于调用toArray。
其中参数idx,可以是负数,比如$(‘div’).get(-2),表示获取倒数第二个div元素。

#first
获取第一个元素,其实现竟然没用通过get来做,
其实现如下:
[quote]$.fn.first = function() {
var el = this[0];
return el && !isObject(el) ? el :$(el);
};[/quote]
取出第一个元素后,要判断是否不是对象,如果不是的话,返回的是$实例。
比如$([{x:1},2,3]).first(),返回的不是{x:1},而是$({x:1}),进而可以继续调用其他方法。
好奇怪的设计,理由个人不清楚。

#last
类似first,取出最后一个:
[quote]$.fn.last = function() {
var el = this[this.length – 1];
return el && isObject(el) ? el : $(el);
};[/quote]

#push
因为数组有个push方法,其直接借用了:

$.fn.push = [].push;

#sort
直接借用数组的:

$.fn.sort = [].sort;

#splice
直接借用数组的:

$.fn.splice = [].splice;

#indexOf
直接借用数组的:

$.fn.indexOf = [].indexOf;

#slice
但是slice,如果简单直接借用数组的,那么返回的是个数组。
而zepto需要返回的$实例对象。因此借用后,还要封装成zepto实例:
[quote]$.fn.slice = function() {
return $([].slice.apply(this, arguments));
};[/quote]

#forEach
数组对象本身就有forEach方法,那么直接借用其即可:

$.fn.forEach = [].forEach;

#each
each接口与forEach接口不一样,在之前的文章还专门吐槽过。。
实现如下:
[quote]$.fn.each = function(callback) {
[].every.call(this, function(el, idx) {
return callback.call(el, idx, el) !== false;
});
return this;
};[/quote]
借用数组的every的方法,每次调用回调后,看其结果返回值是否false?
这样可以实现类似break的效果。
最后返回this,支持链式调用。

#map
实现如下:
[quote]$.fn.map = function(fn) {
return $($.map(this, function(el, i) {
return fn.call(el, i, el);
}));
};[/quote]
其调用了工具方法map,这样首先返回的是数组对象,可以参考$.map的实现,
而实例map方法要求返回的是$实例对象的,而不是数组对象。

#reduce
直接借用数组的:

$.fn.reduce = [].reduce;

#eq
有人经常把eq和get搞混。
eq返回的$实例,而get是其中dom元素。
其实现如下:
[quote]$.fn.eq = function(idx) {
return idx === -1 ? this.slice(idx) : this.slice(idx, +idx + 1);
};[/quote]
这个跟slice有关,从上面知道slice调用了数组的slice,
比如[1, 2, 3].slice(-1),得到是[3],
而[1, 2, 3].slice(-1, 0),是空数组,
要得到最后一个只能使用[1, 2, 3].slice(-1),
而其他是正常的,比如得到倒数第二个:
[1, 2, 3].slice(-2, -1),是[2]。

#concat
zepto对象合并方法。返回的结果仍然是数组:
[quote]$.fn.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);
};[/quote]

其中zepto.isZ用来判断是否是$实例。
遍历所有参数,如果本身是zepto实例,那么就转化成数组,再添加到数组args中。
然后借用数组的concat方法。
注意后面的zepto.isZ(this) ? this.toArray() : this
原因可能$.fn.concat也可能被其他函数借用,而不是作为实例方法调用。例如源码中的内部方法:
[quote]function flatten(array) {
return array.length > 0 ? $.fn.concat.apply([], array) : array;
}[/quote]

#pluck
pluck这个英文单词的意思是“采、摘”的意思。
比如$(‘div’).pluck(‘id’),会得到由id组成的数组。
prototype.js中有此api,而一般函数式库中也有类似的api,比如underscore.js
实现用$.map即可:
[quote]$.fn.pluck = function(property) {
return $.map(this, function(el) {
return el[property];
});
};[/quote]

#总结
上面的这些方法,是集合的通用常见方法。
比如数组有个filter,为啥没分析呢?(后续会分析的)
$.fn.filter的参数selector,跟数组不一样的。

前端模块化开发教程|沈阳前端开发招聘信息|南通前端开发招聘|前端微信开发招聘

» 本文来自:前端开发者 » 《【Zepto】Web前端开发框架源码_集合方法》
» 本文链接地址:https://www.rokub.com/3907.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!