首页 > 代码库 > jQuery源码笔记——三

jQuery源码笔记——三

将类数组对象转化为数组对象

javascript中有许多类数组对象,比如HTMLCollection,NodeList,arguments。她们的特点是和数组一样有length属性,并且有0,1,2这样的位置属性。在代码编写中我们经常需要将他们转化为数组对象。

//mini类数组对象var arrayLike = {    0: "a",    1: "b",    2: "c",    length: 3}console.log(Array.prototype.slice.call(arrayLike))

我们来详细分析一下Array.prototype.slice.call(arrayLike)。数组的中有slice方法,存放在数组的原型中也就是Array.prototype.slice,它操作的返回值是一个数组;call具有修改上下文的作用,本例就是将slice的上下文改为arrayLike。所以这句话就实现了将类数组对象转化为数组对象的功能。

.get()实现

var jQuery = function( selector, context ) {        return new jQuery.fn.init( selector, context );};jQuery.fn = jQuery.prototype = {    init: function(selector){        this.selector = selector;        //从IE8之后提供了querySelectorAll,我们先利用它mini化选择器        //返回的是伪数组对象NodeList        var result = document.querySelectorAll(selector);        //将NodeList转化为jQuery对象。        for(var i = 0;i < result.length;i++){            this[i] = result[i]         }        //模拟jQuery对象的length属性        this.length = result.length;    }}jQuery.fn.init.prototype = jQuery.fn//不利用extend ,直接向原型里添加属性方法getjQuery.fn.get = function(index) {        return index != null ? (index < 0 ? this[this.length + index]:this[index]):Array.prototype.slice.call(this);}//测试console.log(jQuery("div").get(0))

.get的作用是转化为DOM节点,或者是DOM节点数组。注意一些特别的情况。

.eq()实现

var jQuery = function( selector, context ) {        return new jQuery.fn.init( selector, context );};jQuery.fn = jQuery.prototype = {    selector: "",    init: function(selector){        //仍然是mini的选择器。        var result = document.querySelectorAll(selector);        for(var i = 0;i < result.length;i++){            this[i] = result[i]         }        this.length = result.length;    },    pushStack: function( elems ) {        //将空jQuery对象和elems合并        var ret = jQuery.merge( this.constructor(), elems );        //设置前一个对象,作回来的索引。        ret.prevObject = this;        // 新形成jQuery的对象        return ret;    },    eq : function( i ) {        //将负数位置转化为正数位置        var j = + i + ( i < 0 ? this.length:0);        //在范围内返回指定对象包成的数组,否则返回空数组        return this.pushStack((j >= 0&& j<this.length)?[this[j]]:[])    },    //将原型的构造函数设置为jQuery,可以用jQuery.constructor创造新的空对象;相关语句this.constructor;jQuery.prototype;    constructor : jQuery}jQuery.fn.init.prototype = jQuery.fn//将两个类数组对象或数组对象合并,并设置,lengthjQuery.merge = function( first, second ) {        var len = +second.length,            j = 0,            i = first.length;        for ( ; j < len; j++ ) {            first[ i++ ] = second[ j ];        }        first.length = i;        return first;};//测试console.log(jQuery("div").eq(0))

先讲两个相关函数jQuery.fn.pushStatic和jQuery.merge。

写在jQuery.fn里的函数实际写在原型里,用到这个原型的构造函数都会继承;而写在jQuery里的实际是在一个独立的jQuery对象,只能通过jQuery.[函数名]的形式引用。

merge实际的功能是合并两个数组或者类数组对象,放到第一个对象中,并设置他们合并后的长度。pushStatic调用了merge,第一个参数为jQuery空对象(this.constructor()),将第二个数组或者类数组合并到jQuery空对象中,形成新的jQuery对象,并返回。

eq的功能就是get的功能多一个转化成jQuery对象,调用pushStatic,并返回其返回值一个新的jQuery对象。

first和last和end

  first: function() {        return this.eq( 0 );    },    last: function() {        return this.eq( -1 );    },    end: function() {        return this.prevObject || this.constructor(null);    },

jQuery源码笔记——三