源码学习第七天(水滴石穿)

// 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节点对象入栈,这个方法给用户使用的人不多,但是在另外的方法封装需要用到栈的知识,所以需要了解一下。

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 {  }

原文地址:https://www.cnblogs.com/wchjdnh/p/10786295.html