jQuery
源码学习第二节。
今天看下简化框架的第二部分:line: (146 - 225) 为jQ对象添加一些方法和属性
。
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
length: 0,
// 添加原型方法和属性...
}
从上段代码中可以看到,jQuery
对象作为构造函数,在其原型上定义了一些属性和方法,同时其原型也被指向jQuery
对象的属性fn
上面。
jQuery
原型对象jQuery.prototype
有若干个属性和方法:constructor
、length
、toArray()
、get()
、pushStack()
、each()
、map()
、slice()
、first()
、last()
、eq()
、end()
等。
其中属性constructor
指向构造器即jQuery
对象。length
属性默认值为0,为对象添加属性length
,感觉这是要把对象作为类数组来处理,且看后续的代码阅读中能发现用在哪,暂时先不关注。
至于定义的方法,下面一个个来看。首先需要明确,这些方法都是jQuery
实例对象的方法;其次对于js中call
的作用要有深刻的理解,才不会看晕。
toArray
方法:返回一个包含jQuery对象集合中的所有DOM元素的数组。这个方法不接收任何参数。所有匹配的DOM节点都会包含在一个标准的数组中。
//jQuery源码
var arr = [],
slice = arr.slice;
jQuery.prototype = {
toArray: function() {
return slice.call( this );
}
}
//demo.html
<body>
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
</body>
console.log($('li').toArray());
//打印
// [li, li, li, li]
get()
方法:如参数num
为int数值,则返回一个所有匹配DOM中第num
个的元素集合,否则就返回所有匹配的元素数组
jQuery.prototype = {
get: function(num) {
//返回所有元素的数组
if(num == null){ //
return slice.call( this )
}
//只返回指定索引的匹配元素
return num<0?this[num+this.length]:this[num];
}
}
//demo.html
console.log($('li').get(1));
console.log($('li').get());
//打印结果:
// <li>b</li>
// [li, li, li, li]
这里有个小知识点:参数num
不传时值为undefined,undefined == null
结果为true
,undefined === null
结果则为false
。
pushStack()
方法:用于将一个DOM元素集合加入到jQuery栈。
jQuery.prototype = {
pushStack: function( elems ) {
// 创建一个新的jQuery匹配元素集合
var ret = jQuery.merge( this.constructor(), elems ); //jQuery对象的merge方法暂时还未看到,先不管
// 通过this把老的jQuery原型对象挂载到新建的ret对象的prevObject属性上云,这可以看作是jQuery对象的一个引用吧
ret.prevObject = this;
// 返回这个新创建的元素集合
return ret;
},
}
var res = jQuery.prototype.pushStack($('li'));
console.log(res);
// 打印结果看下图
图1
这个方法其实作用就是把元素集合添加到一个新的对象中,并且这个对象还具有jQuery
对象的引用,所以也就是具有jQuery
对象的所有方法和属性,链式调用起来妥妥的呀。
例如这个沙雕作法:向 jQuery
栈中先压入一些元素,然后再删除它们,之后再退回到之前刚压入栈的状态。
$().pushStack( document.getElementsByTagName("div")).remove().end();
虽然沙雕,但很好玩有没有,感觉在某些地方会发挥奇妙的作用。这个方法的思路也非常值得借鉴,写原生时直接用也很妥了。
时间关系,今天先到这,剩下的明天再写吧。
喜欢本文请扫下方二维码,关注微信公众号: 前端小二,查看更多我写的文章哦,多谢支持。