类数组是jQuery框架的专有概念,它描述了jQuery对象的基本形态。我们曾经介绍过,jQuery选择器能够匹配一个或多个DOM元素,并把这些元素打包到一个数据集中返回,然后提供众多操作这个数据集合的方法。那么类数组到底是一类什么数据?它的结构是什么样的?它又包含了那些基本特性?本节将就这些个问题专门介绍。
2.5.1 定义类数组
在JavaScript中,最高效的数据仓库就是数组了,也就是说数组是最佳数据集合结构。也许我们可以采用下面的方法让jQuery返回的数据都存储到数组中。
- jQuery.fn.prototype=new Array();
然后,通过下面方法来实现数组继承机制。
- jQueryjQuery.fn.prototype.constructor=jQuery
这样jQuery对象就继承了数组的所有特性,又可以在jQuery对象中进行数组的功能扩展。
但是,jQuery并没有这样做,也就是说它抛弃了通过继承Array的途径来实现内部包含数据集合的功能,而是采用Array-Like对象结构来实现。
Array-Like(类数组)对象,实际上就是对象,但是它类似数组。如果从集合角度分析,对象和数组其实都是一家人,只不过一个是无序的,一个是有序的。而对于数组来说,它主要表现为带有元素下标和length属性。当数组元素增减时,length属性会自动进行跟踪,反映这种变化。
例如,下面的代码是jQuery.fn.init()构造函数中第一种实现,即当选择符为DOM元素时,jQuery定义jQuery对象的过程。
广州网站建设,网站建设,广州网页设计,广州网站设计
- if ( selector.nodeType ) {
- this[0] = selector;
- this.length = 1;
- this.context = selector;
- return this;
- }
首先,它通过this[0]来直接设定第一个位置的DOM元素,同时设定this的length属性值为1。这里可以看到对象采用数组的key/value(键/值)对方式存储在对象中。上面代码可以使用对象直接量表示为以下方式。
- {
- 0 : selector,
- length : 1
- }
实际上,数组继承于对象。运算符[]与运算符{}所存储的数据都是相同的。不过,对于数组来说,它会把下标index作为对象属性的key,把数组中的值作为对应的value。
如果是多元素的jQuery对象,jQuery会首先调用jQuery.makeArray(selector)函数把集合(类数组)转换成数组。通过分析,数组和对象都可以采用object[attr]语法格式取得key对应的value。对于类数组来说,要实现下标访问对象,则必须要求其实现length属性,有了length的长度,那么就可以从0~length-1的key属性中取得对应的value。
例如,jQuery利用下面的函数将类数组对象转换为数组对象。类数组对象有length属性,其成员索引为0~length-1。
广州网站建设,网站建设,广州网页设计,广州网站设计
- //把类数组对象的元素全部推进数组对象
- makeArray: function( array ) {
- var ret = [];
- //如果参数存在
- if( array != null ){
- var i = array.length;
- //单个元素,但window、string、function有length的属性,加其他的判断
- if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
- ret[0] = array;
- else //类数组的集合
- while( i )
- ret[--i] = array[i];
- }
- return ret; //返回数组对象
- }
下面这个函数能够把任何类数组对象转换为jQuery对象。
- //把类数组对象的元素全部推进当前jQuery对象中
- setArray: function( elems ) {
- //初始化长度
- this.length = 0;
- // push()方法会在原始length属性上递加其值
- Array.prototype.push.apply( this, elems );
- return this;
- }
当然添加元素时,会调用Array.prototype.push函数自动修改对象的length属性值。实际上,Array的方法都可以自动改变length的值,从而在对象的key/value对中完成无序到有序或重新排序的工作。
setArray()函数只会改变当前jQuery对象的集合,它会清除这个对象集合中以前的元素。但是有的时候我们想保存原来集合中的元素,同时也想能就新传入的元素进行jQuery对象的操作。因此,jQuery又定义了pushStack()函数,新建一个jQuery对象的同时保存对原来对象的引用。这样就可以在需要时使用自己所要的对象了。
广州网站建设,网站建设,广州网页设计,广州网站设计
- //把类数组对象的元素全部推进当前的jQuery对象
- pushStack: function( elems, name, selector ) {
- //把参数elems封装进一个新的jQuery对象中,定义类数组
- var ret = jQuery( elems );
- // 把旧对象作为一个属性封装到ret中
- ret.prevObject = this;
- ret.context = this.context;
- if ( name === "find" )
- ret.selector = this.selector + (this.selector ? " " : "") + selector;
- else if ( name )
- ret.selector = this.selector + "." + name + "(" + selector + ")";
- //返回新的格式化的数据集
- return ret;
- },
该函数返回的是新构建成的对象,它有着jQuery对象的全部功能,同时还可以通过prevObject来访问原来的老对象。



