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 ,直接向原型里添加属性方法get jQuery.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 //将两个类数组对象或数组对象合并,并设置,length jQuery.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); },
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。