学习源码第六天(加油别放弃)

 // HANDLE: $(function)
        // 处理入口函数简写
      } else if (jQuery.isFunction(selector)) {  //JQuery.isFunction()判断是不是函数,$(function(){})这种,是的话
        return rootjQuery.ready(selector);       //返回$(document).ready(function(){}),
      }
    //处理$($('#div')) 这种怪癖的写法
      if (selector.selector !== undefined) {
        this.selector = selector.selector; //就把'#div'这个字符串给this,相当于$($('#div')) -> $('#div')
        this.context = selector.context;   //这个步骤就是把查找域给this
      }

      return jQuery.makeArray(selector, this);
    },

比较简单的代码直接注释中解释,重点来说说jquery中的makeArray方法

        var e=null;
        console.log( $.makeArray(e) )  //打印[],
        console.log( $.makeArray({ a:1,b:2 })) //打印[{ a:1,b:2 }]
        console.log( $.makeArray( {'0':1 ,'1':2} ));  //打印[{'0':1 ,'1':2}]
        console.log( $.makeArray( {'0':1 ,'1':2,'a':'哈哈',length:2} ));// [1,2]

以上结果说明,null 或 undefined通过$.makeArray就会变成[],没有length属性的对象会把对象当成一个元素,生成一个数组,有length属性的,首先除了数字字符属性其他属性名的都不要,然后看length属性值为多少,去选取从'0'到length-1的数字属性的值去变成一个数组。说个不常见的现象:两个参数length和如果是-1这种无意义的值,转变后length:NaN,属性也不对

说完了$.makeArray()的用法,但是里面传了两个参数,这比较不常见但是,可以类比$.merge猜一下:就是返回的结果不是数组了,而是一个有length属性的伪数组(对象)。

console.log($.makeArray({'0':1,'1':2,'a':3,length:2},{length:1}));  //{1: 1, 2: 2, length: 3}
console.log($.makeArray( {'0':1 ,'1':2,'a':3,length:2},{'0':5,'1':8,'2':9,'a':'哈哈',length:2} ));//{0: 5, 1: 8, 2: 1, 3: 2, a: "哈哈", length: 4}

 

总结一下:$.makeArray的第二个参数必须有length属性(默认是数组),第二个参数如果写了对象,还发生了合并操作就是把第一个参数的数字属性值添加(不是覆盖)到第二个参数对象里,length相加,如果两个参数有重名,看第二个参数的length,如果为0,第一个参数为准,如果不为0,以第二参数为准,并且第一个参数添加进来往后排(特别注意:往后排不是简单地+1,而是看合并后的总length,去添加属性数字值),第二个参数的非数字属性不要动。

简单来说:与$.merge()的区别除了参数要求,合并的时候$.merge()会根据本身length值选取出数字属性的部分,而$.makeArray()则会保留所有属性。

 

return jQuery.makeArray(selector, this);

 

再来看一下,首先这句代码是返回init : function(){}里面的,也就是说默认返回的是这么一个对象,特征是有数字属性,有length属性,还有一些其他属性(前面有context)。

其实在各个if判断里有些return了,所以这里只是告诉那些没return的,执行这个return,其实就是最后的情况去return,一个意思

 

回顾一下到底init:function(){}干了什么事情:返回了一个this,这个this对象属性里有原生节点,还有length属性。

// Start with an empty selector
    selector: '', //其实就是给selector赋一个初值''

    // The default length of a jQuery object is 0
    length: 0,    //其实就是给length赋一个初值0

    toArray: function() {
      return core_slice.call(this); //core_slice是一个前面定义的方法[].slice,通过借用 相当于把this当成一个数组去掉用,所以this必须是一个有length的对象才行
    },

$(选择器).toArray()方法:jQuery对象转数组,与$.makeArray()的区别在于$(选择器).toArray()只能把jQuery对象转成数组,后者只要是对象都能转(而且是$去调用),转的方式上文中具体讲了一些。其实toArray()是为了以后的封装方法做准备的,单独的使用不常用,所以别觉得他的功能其他方法也有就觉得多余,其实其他方法在封装的时候需要用到这个方法。从另一个角度看,下文封装了$(选择器).get()功能更强大,但是写的更少,体现了他的宗旨:''write Less,Do More''

init方法返回的jQuery对象可以用$.toArray()去转成数组。

// Get the Nth element in the matched element set OR
    // Get the whole matched element set as a clean array
    get: function(num) {
      return num == null
        ? // Return a 'clean' array
          this.toArray()
        : // Return just the object
        num < 0
        ? this[this.length + num]
        : this[num];
    },

$(选择器).get()注意这些方法都是定义在init里的所以使用他们应该是一个$(选择器)的形式,而不是一个$.的形式,$.的形式不是写在init里的

$('div').get() => 相当于$('div').toArray()  ;    $('div').get(0)  <=> $('div').toArray()[0]  ;$('div').get(n)  <=> $('div').toArray()[n]( n > 0 )  ;  $('div').get(n)  <=> $('div').toArray()[$('div').toArray().length - n] (n < 0 也就是倒着数,不过倒着数最后一项是 -1 ,因为 -0 就是0 是第一项)

其实$('div').get()实现方法用了三元运算符的嵌套,把代码拉成一行num == null? this.toArray(): num < 0 ? this[this.length + num] : this[num]; 首先分析一下首选算num == null(调皮了,其实这里写undefined也是可以的,但是undefined == null) ? 没有传参走 this.toArray() 传参了走 num < 0 ? this[this.length + num] this[num];

在传参的情况下判断num是不是负数:是就取第this.lenth + num 下标的值,不是负数(正数 和  其他类型)取num的值,当然了其他类型this中没有num这个属性,那就返回undefined,

其实在我们看了源码以后其实不难看出,就算不是数字参数,只要是this里面有的属性名传进去就是取到了this[参数名],但是这无任何意义,因为直接this[参数名]不就好了?

posted @ 2019-04-28 00:20  火鸡的呐喊  阅读(172)  评论(0编辑  收藏  举报