一.4-jQuery.prototype对象中的属性与方法(下)
2021-03-05 09:28
标签:info 一行代码 而且 观察 说明 class oar 还需 标签 一.4-jQuery.prototype对象中的属性与方法(下) 标签:info 一行代码 而且 观察 说明 class oar 还需 标签 原文地址:https://www.cnblogs.com/re-is-good/p/12907367.html上一篇写到了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 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)
首先需要知道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 // 对负索引的处理
return this.pushStack(j >= 0 && j 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方法形成新的栈帧。
文章标题:一.4-jQuery.prototype对象中的属性与方法(下)
文章链接:http://soscw.com/index.php/essay/60389.html