一.4-jQuery.prototype对象中的属性与方法(下)
上一篇写到了jQuery.prototype对象的init方法,因为init方法内容较多,因此弄了个上下篇
先列一下jQuery.prototype对象上的方法与属性吧
jQuery.fn = jQuery.prototype = { jquery: core_version, // 49行 core_version = "2.0.3" constructor: jQuery, init: function(){}, selector: "", length: 0, // 伪数组的元素个数 toArray: function(){}, get: function(){}, pushStack: function(){}, each: function(){}, ready: function(){}, slice: function(){}, first: function(){}, last: function(){}, eq: function(){}, map: function(){}, end: function(){}, push: core_push, // 其实这个方法就是Array.prototype.push。这样可以方便压缩代码。见53行及47行 sort: [].sort, splice: [].splice }
selector属性, length 属性不用介绍了。
1. toArray
204行, 将jQuery伪数组转为数组
toArray: function () { return core_slice.call(this); // [].slice.call(this) }
2. get
209-217行
有时候我们需要得到node节点,通过这个方法便可以得到相应的节点了
get: function (num) { return num == null ? // Return a ‘clean‘ array this.toArray() : // Return just the object (num < 0 ? this[this.length + num] : this[num]); }
如果不传入参数或者传入null,就调用toArray方法,将jQuery伪数组转为数组
如果num为负数,就加上jQuery对象的length,这样就能转为对应的正数了
一般一个jQuery对象长这个样子
jQuery = { 0: li, // 这里的li是node节点,请注意 1: li, 2: li, length: 3 } // 其它属性就没写了
$("li").get(-1), 这时jQuery对象的长度是3,-1代表或者这个对象的最后一个node节点。-1+这个jQuery对象的长度 => -1+3 => 2。
3. pushStack
压栈操作,与end方法结合使用
想想这样的操作
$("li").eq(0).css("color", "red"); // 只有第一个li标签变红了,其它li标签没有变红。
$("li")后,jQuery对象会长这个样子
jQuery = { 0: li, // 这里的li是node节点,请注意 1: li, 2: li, length: 3 }
eq(0)是返回对象的第一个元素(对象的形式)。
怎么只让第一个元素变红呢? 直接将其它元素去掉? 这个不太行吧,可能用户还需要操作其它元素呢?
比如要完成这样的操作,让第一个li标签变红,第二个标签变蓝,一行代码完成。
$("li").eq(0).css("color","red").end().eq(1).css("color", "blue")
这时候我们就需要使用pushStack了
先看看源代码的实现吧(221-232)
pushStack: function (elems) { // Build a new jQuery matched element set // this.constructor() 返回新的jQuery对象, elems是一个对象 var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference) // 保存之前的状态。在用户调用end方法时,该对象就会被返回 ret.prevObject = this; ret.context = this.context; // Return the newly-formed element set return ret; }
首先需要知道merge方法是干什么?(merge的用法已经在上篇说明了,详细的可以去上篇看)
merge接受两个参数(可以是数组或者伪数组),然后第一个参数会融合第二个参数的属性。因此第一个参数的值会被修改。第一个参数也会被返回。
为什么叫这个名字
当我们调用$("li")时,我们的操作(如css,html)都会落到栈顶的头上
当我们调用 $("li").eq(0)时,会push一个新栈帧。这时我们的操作就只会落在第一个li标签身上了。
目前栈底会被上一层栈帧引用,通过prevObject引用
当我们想要对非栈顶元素进行操作时,就可以调用end方法,每调用一次,栈就会被pop一次。
272-274行 end实现
end: function () { return this.prevObject || this.constructor(null); }
看,end方法便直接返回prevObject,如果没有的话,就返回一个新的jQuery对象。
each方法是直接调用工具方法的,暂时不说(可以看出加强版的forEach循环,可以遍历伪数组)
ready方法涉及延迟对象的知识,讲到延迟对象时再回来讲这个。
4. slice方法
248-250行
slice: function () { return this.pushStack(core_slice.apply(this, arguments)); } // 这里用了apply是因为我们可以需要接受参数 // 注意下 这里也调用了pushStack方法。 $("li").slice(1, -1) .css("color", "red"); // 可以观察下这里的效果
5. first, last, eq方法
252-262行
这三个方法其实是一起的。而且eq方法是主要的实现, first和last也是直接调用eq方法的。
$("li").first().css("color", "red"); // 让第一个li元素变红 $("li").eq(1).css("color", "red"); // 让第二个li元素变红
先讲讲eq方法的实现吧
eq: function (i) { var len = this.length, j = +i + (i < 0 ? len : 0); // 对负索引的处理 return this.pushStack(j >= 0 && j < len ? [this[j]] : []); // 索引的范围[0, len-1], 否则置一个空数组 }
看起来pushStack方法很重要,因此需要多多理解下pushStack方法的背后操作
first方法和last方法是直接调用eq方法的。
first: function () { return this.eq(0); }, last: function () { return this.eq(-1); }
6. map
266-270行
map: function (callback) { return this.pushStack(jQuery.map(this, function (elem, i) { return callback.call(elem, i, elem); })); }
前面的eq,first,last,slice方法是通过索引来筛选对应的元素的。但有时候我们需要特别的筛选。如下
$("li").map(function(index, ele){ if (ele.className === ‘default‘){ return ele; } })
这个将筛选li元素(li元素的class属性值必须是default),只有li元素的class属性名为default时,才会返回。
我们需要查看下jQuery.map工具方法
这个方法其实是一个加强版的Array.prototype.map方法,可以对伪对象进行相应操作。如果熟悉数组的map方法的话,应该比较容易。
因此我先说说数组的map方法吧
var ret = [1,2,3,4].map(function(ele, index,array){ return ele*ele; }) console.log(ret); // [2,4,9,16] 返回一个新数组,我们可以对原数组的元素进行特定的操作,回调函数返回的数值将自动成为新数组的元素
需要注意,jQuery.map工具方法与数组的map的不同点。
首先jQuery.map工具方法支持对伪数组进行操作(返回的是数组)。
其次jQuery.map会根据实际情况来返回新的数组。(因此新数组的长度与原数组的长度并不一致), 数组的map确是原数组长度与新数组长度一致
第三回调函数的参数并不同,jQuery.map回调函数的第一个参数是数组的索引,第二个参数是数组的元素,没有第三个参数(原数组)
数组的map回调函数的第一个参数是数组的元素,第二个参数是数组的索引,第三个参数是原数组。
调用jQuery.map方法后会根据我们的回调函数来生成新数组,然后再调用pushStack方法形成新的栈帧。
相关推荐
EdwardSiCong 2020-11-23
85477104 2020-11-17
hhanbj 2020-11-17
81427005 2020-11-11
seoppt 2020-09-13
honeyth 2020-09-13
WRITEFORSHARE 2020-09-13
84483065 2020-09-11
momode 2020-09-11
85477104 2020-08-15
83510998 2020-08-08
82550495 2020-08-03
tthappyer 2020-08-03
84901334 2020-07-28
tthappyer 2020-07-25
TONIYH 2020-07-22
tztzyzyz 2020-07-20
83510998 2020-07-18
81463166 2020-07-17