返回目录:电脑蓝屏
不管zepto对象,还是jquery对象,其本质上都是一个类数组对象。
什么是类数组对象呢,网上有很多资料,我也专门写过《文章》。
具体来说就是有length属性,可以按下标来访问。
本文从这个角度来分析一些zepto实例方法。
#size
既然是类数组,有length属性,看此集合的大小。
其实现应该说是最简单的:
$.fn.size = function() {return this.length;
};
其中$.fn,应该没人不知道吧,
$是个函数,$.fn是$.prototype。
#toArray
把$实例变成真正数组。
可以以如下的方式实现:
$.fn.toArray = function() {return [].slice.call(this);
};
当然了其源码不是这么做的,内部调用了get方法:
$.fn.toArray = function() {return this.get();
};
#get
我们可以使用$('div')[0]获取第一个元素,那么也可以使用$('div').get(0)来做。
其实现如下:
$.fn.get = function(idx) {return idx === undefined ? [].slice.call(this) : this[idx >= 0 ? idx : idx + this.length];
};
如果没传参数,那么返回整个数组,也就相当于调用toArray。
其中参数idx,可以是负数,比如$('div').get(-2),表示获取倒数第二个div元素。
#first
获取第一个元素,其实现竟然没用通过get来做,
其实现如下:
$.fn.first = function() {var el = this[0];
return el && !isObject(el) ? el :$(el);
};
取出第一个元素后,要判断是否不是对象,如果不是的话,返回的是$实例。
比如$([{x:1},2,3]).first(),返回的不是{x:1},而是$({x:1}),进而可以继续调用其他方法。
好奇怪的设计,理由个人不清楚。
#last
类似first,取出最后一个:
$.fn.last = function() {var el = this[this.length - 1];
return el && isObject(el) ? el : $(el);
};
#push
因为数组有个push方法,其直接借用了:
$.fn.push = [].push;
#sort
直接借用数组的:
$.fn.sort = [].sort;
#splice
直接借用数组的:
$.fn.splice = [].splice;
#indexOf
直接借用数组的:
$.fn.indexOf = [].indexOf;
#slice
但是slice,如果简单直接借用数组的,那么返回的是个数组。
而zepto需要返回的$实例对象。因此借用后,还要封装成zepto实例:
$.fn.slice = function() {return $([].slice.apply(this, arguments));
};
#forEach
数组对象本身就有forEach方法,那么直接借用其即可:
$.fn.forEach = [].forEach;
#each
each接口与forEach接口不一样,在之前的文章还专门吐槽过。。
实现如下:
$.fn.each = function(callback) {[].every.call(this, function(el, idx) {
return callback.call(el, idx, el) !== false;
});
return this;
};
借用数组的every的方法,每次调用回调后,看其结果返回值是否false?
这样可以实现类似break的效果。
最后返回this,支持链式调用。
#map
实现如下:
$.fn.map = function(fn) {return $($.map(this, function(el, i) {
return fn.call(el, i, el);
}));
};
其调用了工具方法map,这样首先返回的是数组对象,可以参考$.map的实现,
而实例map方法要求返回的是$实例对象的,而不是数组对象。
#reduce
直接借用数组的:
$.fn.reduce = [].reduce;
#eq
有人经常把eq和get搞混。
eq返回的$实例,而get是其中dom元素。
其实现如下:
$.fn.eq = function(idx) {return idx === -1 ? this.slice(idx) : this.slice(idx, +idx + 1);
};
这个跟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]。
总结上面的这些方法,是集合的通用常见方法。
比如数组有个filter,为啥没分析呢?(后续会分析的)
$.fn.filter的参数selector,跟数组不一样的。所以没有放在本文。
本文完。