源码学习第七天(水滴石穿)
Posted wchjdnh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了源码学习第七天(水滴石穿)相关的知识,希望对你有一定的参考价值。
// Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function(elems) { //elem可以是数组和伪数组 // Build a new jQuery matched element set var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference) ret.prevObject = this; ret.context = this.context; // Return the newly-formed element set return ret; //jQuery节点对象 },
jQuery节点对象入栈,这个方法给用户使用的人不多,但是在另外的方法封装需要用到栈的知识,所以需要了解一下。
据上图结合代码所知,$(‘div‘).pushStack($(‘span‘))就是把span添加到栈中,这时候返回的是$(‘span‘)。
具体来说说代码的写法,var ret = jQuery.merge(this.constructor(), elems);这一句体现了花式秀js,其实this.constructor()就是jQuery()的意思,首先this指向了jQuery的实例,this.constructor就是原型的constructor属性指向jQuery。这句话的意思就是把添加的jQuery节点对象与一个空jQuery节点对象合并,返回一个新的jQuery节点对象,再给这个对象添加context属性,prevObject属性存上一个jQuery节点 res.prevObject = this;这个this指向init,返回新的jQuery节点res
最重要的一点是每次调用$(‘ ‘).pushStack(elem)都是重新开辟一个栈,把elem添加到$(‘ ‘)上,然后返回一个整体的res对象,顺带一说,如果$(‘ ‘)有多个节点,多个(jQ)节点属于同一层,而不是一个( jQ )节点一层。[ 每个栈底层都有一个$(document),再下一层就没了,返回的res就是init{} ]
each: function(callback, args) { return jQuery.each(this, callback, args); }, ready: function(fn) { // Add the callback jQuery.ready.promise().done(fn); return this; }, slice: function() { return this.pushStack(core_slice.apply(this, arguments)); }, first: function() { return this.eq(0); }, last: function() { return this.eq(-1); }, eq: function(i) { var len = this.length, j = +i + (i < 0 ? len : 0); return this.pushStack(j >= 0 && j < len ? [this[j]] : []); }, map: function(callback) { return this.pushStack( jQuery.map(this, function(elem, i) { return callback.call(elem, i, elem); }) ); }, end: function() { return this.prevObject || this.constructor(null); }, // For internal use only. // Behaves like an Array‘s method, not like a jQuery method. push: core_push, sort: [].sort, splice: [].splice
接下来就是各种常用方法each、ready、slice、first、last、eq、map、end,各个方法间有依赖关系。
each循环:这个each循环是$(‘ ‘).each() 是根据$.each()进一步的封装。
ready:入口函数,也是调用内部封装的函数,要以后了解到调用函数的意义才行
slice:截取,通过栈方法的和借用数组的方法 ‘this.pushStack(core_slice.apply(this, arguments));‘ 借用中的this指向调用的this,也就是init;core_slice也就是[].slice,arguments参数集合,call并不能用参数集合,只能一个一个写出来。
eq: j = +i + (i < 0 ? len : 0); 一句话就解决了负数和正数的i的取值,正数的时候+i + 0,负数的时候+i+jQuery节点对象长度(+表示转数字类型); ‘return this.pushStack(j >= 0 && j < len ? [this[j]] : []);‘ 如果j也就是处理后的数字在[0,len)之间就把[ this[j] ]添加到栈,否则就将[ ]添加到栈 (this[j]就是原生DOM节点 ),通过返回的res得到想要的jQuery节点对象。
first、last都是在eq的基础上操作 first:qe(0) last:eq(-1)
map:映射,调用了jQuery.map( )
end:往栈里面走一层 ‘return this.prevObject || this.constructor(null);‘ 如果prevObject存在也就是下一层有值,就返回,没有就返回$(null) => init { }
以上是关于源码学习第七天(水滴石穿)的主要内容,如果未能解决你的问题,请参考以下文章