`
jljlpch
  • 浏览: 323268 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

jquery对象的数组特性

阅读更多
2.3、jquery对象的数组特性
从上面一小节可以看出jquery构建函数完成了查找或转换或其它的功能,其结果就是找到元素,查找,转找不过是方式而已。找到元素就得找个地方去存储起来。这个地方是就是这一节要分析的。
存储有序数据的地方(集合)在JS中最好的当然是数组。那么又如何在jQuery内面实现数组呢?可以采用如下的方式:
jQuery.fn.prototype=new Array();
在上一节中的this.setArray(arr)函数中加上
  Array.apply(this,arr);
如果还要完美一点,就加上:
jQuery.fn.prototype.constructor=jQuery。
这样我们继承了数组的所有特性,又可以在Jquery对象进行数组的功能扩展。但是jQuery并没有这样采用继承Array而实现这个内部的集合。它采用了Array-Like的对象的实现(见JavaScript: The Definitive Guide, 5th Edition7.8节)。
类数组的对象还是对象,只不过像数组。数组与对象其实是没有什么好大的区别的,有序和无序的集合是它们区别。这个区别反应在数组有的length属性。当添加元素它会自动加上相对的个数,当删除元素,它会自动减去相对的个数。
看一下jQuery是怎么实现的:
// 第一种情况 Handle $(DOMElement)单个Dom 元素,忽略上下文
		if (selector.nodeType) {                                            ②
			this[0] = selector;
			this.length = 1;
			return this;
		}		
这是它的第一种实现方法,通过this[0]来直接设定第一个位置的Dom元素,同时设定length=1。这里我们可以看出对象与数组一样都是采用key/Value对的形式存在对象中。上面的Json形式为{0:aDom,length=1}。这里细细分析一下数组,数组是继承于对象。其[]的解释分析最终结果可以看作{}构的对象,对[]或数组的构建时会进行把index(如0.1,….)做为对象属性的key。把数组中的值做为其对应的value。同时改变length的值。这也就是说为什么本质上对象与数组没有多大的区别。在很多的源码中,如YUI中都采用对象的形式来构建多维数组。
this.setArray(jQuery.makeArray(selector));
是其第二种实现的方法,上面实现是单个的元素,这个实现的多个元素的集合。它首先调用了jQuery.makeArray(selector)这个静态方法把集合(类数组)转换成数组。
上面已经分析了数组和对象都可以采用obj.[attr]的形式来取得其key对应的value。对于集合或类数组,必须要求其实现length属性,有了length的长度,那么就从0~length-1的key属性中取得对应的value就可以了:
//把类数组的集合转换成数组,如果是单个元素就生成单个元素的数组。
makeArray: function( array ) {
	var ret = [];
	if( array != null ){	var i = array.length;
	//单个元素,但window, string、 function有 'length'的属性,加其它的判断
	  if( i == null || array.split || array.setInterval || array.call )
	  	  ret[0] = array;
	  else//类数组的集合
		  while( i )	ret[--i] = array[i];//Clone数组
	 }
return ret;
	},
生成了一个标准的数组,那么接下来setArray来干什么呢?
// 把array-like对象的元素全部push当前jquery对象。
	setArray : function(elems) {
		this.length = 0;//初始化长度,因为push会在原始的length++
		Array.prototype.push.apply(this, elems);
		return this;
	},
这个调用了Array.prototype.push来自动修改length的属性值(当然是加入了元素)。由此可以推想到Array中众多的方法(如shift)都可以看作改变length的值在对象的key/value对中完成无序到有序或重新排序的工作。实际上Array等是采用C或C++来实现的。但是它构出的JS特性让我们可以这样去思考采用JavaScript的实现方式。
上面的setArray(elems)函数只是会改变当前jQuery对象的集合,它会清除这个对象集合中以前的元素。但是有的时候我们想保存原来的集合中元素,同时也能就新传入的元素进行jquery对象的操作。它提供了pushStack函数来新建一个jQuery对象同时保存原来对象的引用。这样就可能在需要时用到自己所要的对象:
	pushStack : function(elems) {// 采用jQuery构建新对象,同时引用老对象。
		var ret = jQuery(elems);// 构建新的jquery对象
		ret.prevObject = this;// 保存老的对象的引用
		return ret;
	},
返回的是新构建成的对象,有着jQuery对象的全部功能,同时还可以通过prevObject来访问原来的老对象。

构建了类数组,那么还得提供一些方法来操作这个集合,对于集合的操作无非就是定位元素,查找元素,复制(slice)和删除的操作(splice)等。jQuery还提供each,map的扩展。
这些方法只和集合相关,与集合的元素的无关。jQuery提供了众多的和其中元素(DOM元素)相关的方法。

它提供了两个get元素的方法,get(index)和eq(index),不同是get取得是集合中的元素,而eq则是返回该元素的Clone。不会修改数组。其实可以直接通过[i]来代替get(i)。如果get没有参数则是获得全部元素。
// 取到本jquery对象的第几个Dom元素,无参数,代表全部的Dom元素
	get : function(num) {
		return num == undefined ? jQuery.makeArray(this) : this[num];
	},
// 获取第N个元素 。这个元素的位置是从0算起。
	eq : function(i) {
		return this.slice(i, +i + 1);
	},
这两个函数就不用分析了。接下来看看如何实现在集合中定位元素:
/ 找到elem在本jquery对象的位置(index)
	index : function(elem) {
		var ret = -1;
		return jQuery.inArray( // 如是jQuery对象就取第一个元素
				elem && elem.jquery ? elem[0] : elem, this);
	},

// 判断elem元素在array中的位置(index) 静态方法
	inArray : function(elem, array) {
			for (var i = 0, length = array.length;i < length; i++)
				// Use === because on IE, window == document
				if (array[i] === elem)
					return i;
			return -1;
		},
inArray是jQuery的静态方法,而index是通过调用inArray来实现其定位的功能。Index的函数支持的参数可以是jQuery对象或Dom元素,而inArray则是实用方法,支持任何的元素。

Jquery提供了如数组中slice复制的功能的方法,还提供类似concat的静态方法merge。Slice是通过Array中slice来实现的:
  / 代理数组的slice,同样的操作。
	slice : function() {
		return this.pushStack(Array.prototype.slice.apply(this, arguments));
	},
它返回生成新的jQuery对象。这个对象的集合就是要复制后的集合。对于merge,它是静态方法,实现把第二个元素追加到第一个参数的数组中。
// 把second 元素追加到first的数组中。
		merge : function(first, second) {
	 // We have to loop this way because IE & Opera overwrite the length
	 // expando of getElementsByTagName
		var i = 0, elem, pos = first.length;
		// Also, we need to make sure that the correct elements are being
		// returned (IE returns comment nodes in a '*' query)
			if (jQuery.browser.msie) {
				while (elem = second[i++])
					if (elem.nodeType != 8)
						first[pos++] = elem;

			} else
				while (elem = second[i++])
					first[pos++] = elem;

			return first;
		},
Jquery的each是对集合中每个元素都执行回调函数。
	// 当前jquery对象中每个元素都执行callback(index,elem)函数
	each : function(callback, args) {// 返回this
	// 其调用了jQuery的静态方法。prototype中的mothodize是解决这类问题的好方法
		return jQuery.each(this, callback, args);
	},	
它通过调用jQuery.each这个静态方法来完成功能的:
// 对object中的每个对象都执行callback函数进行处理。args仅仅内部用
	 each : function(object, callback, args) {
			var name, i = 0, length = object.length;
			// 和else的处理差不多,args的传参代替object的属性值
			if (args) {
				if (length == undefined) {
					for (name in object)
						if (callback.apply(object[name], args) === false)
							break;
				} else
					for (;i < length;)
						if (callback.apply(object[i++], args) === false)
							break;
	     	} else {
		       // 不是array-like的object,对每个属性进行callback函数的调用
	if (length == undefined) {
	           	for (name in object)
if (callback.call(object[name], name, object[name]) === false)
						break;
				   } else
					// array-like object,采用数组的形式来处理
	 for (var value = object[0];i < length	&& callback.call(value, i, value) !== false; value = object[++i]) {}
			}
			return object;
		},
该静态方法支持第一个参数的类数组(数组)或对象。是数组就对每个元素进行callback的操作。如果是对象,就是对每个属性值进行callback的操作。这个callback回调函数的格式如下:callback:function(index,value)。Index是索引号,value是数组的index对应的元素或对象的第index个处理的属性。如果使用args参数,那callback回调函数的格式如下:callback:function(args)。Args是给回调函数设定参数。再看一下jQuery对象的each。它的第二个参数args就是采用传入的args直接进行给callback设定参数,而不是默认提集合中index和对应的元素,但执行的次数还是集合的length次。

Jquery的map是将一组元素转换成其他数组(通过回调函数返回值组成的)	// 将一组元素转换成其他数组	然后根据这个数组构建新的jquery对象。。
	map : function(callback) {
		return this.pushStack(jQuery.map(this, function(elem, i) {
			return callback.call(elem, i, elem);
		}));
	},
这个函数首先通过jQuery.map(this, function(elem, i){}来把this的jQuery对象集合的每个元素当作回调函数的elem的参数传到回调函数中。而这个回调函数又执行实例方法的map : function(callback)中callback函数,也就是jQuery.map中的回调仅仅是传参代理的功能。jQuery.map通过代理的回调来取得转换而成的元素集合。
接下来就是采用pushStack把这集合的元素构建成新的jQuery对象并返回,同时保存原jQuery对象的引用。
看下Map的静态方法:
    // 返回对elems每个元素都进行操作的callback函数的返回值的集合。
		map : function(elems, callback) {
			var ret = [];			
			for (var i = 0, length = elems.length;i < length; i++) {
				var value = callback(elems[i], i);
				if (value != null)//说明转换的集合的个数可能少于原来的集合
					ret[ret.length] = value;
			}
			return ret.concat.apply([], ret);//采用array的concat实现
		}
Map的静态方法返回每个callback返回的元素组成的数组。

 

分享到:
评论
3 楼 haiyupeter 2012-05-07  
不过说实在的,其实jQuery不是这样就形成类数组对象的,还需要一个,请查看:http://stackoverflow.com/questions/6599071/array-like-objects-in-javascript 或者:http://haiyupeter.iteye.com/admin/blogs/1513403
2 楼 haiyupeter 2012-05-06  
非常牛逼,非常仔细,正是想要找的资料,自己看了半天没看懂jQuery是怎么样模拟数组的,向高人学习了。
1 楼 ybbkd2 2010-02-08  
没看懂...

相关推荐

    jquery实现数组array、集合list、json类型的分页

    本主题将深入探讨如何使用jQuery库来实现数组、集合(如Java中的List)以及JSON类型的分页功能。jQuery作为一款强大的JavaScript库,简化了DOM操作,使得分页功能的实现变得更加简便。 首先,我们要理解分页的基本...

    jquerydom对象的事件隐藏显示和对象数组示例

    在本文中,我们将深入探讨jQuery的DOM对象事件处理、隐藏显示功能以及如何操作对象数组。jQuery作为一个广泛使用的JavaScript库,它简化了HTML文档遍历、事件处理、动画和Ajax交互,使得Web开发更加便捷。 首先,让...

    jquery实现数组array、集合list、json类型的分页支持多个分页

    集合List的分页与数组类似,只是需要考虑List的特性和API。在Java中,List接口提供了如`.size()`用于获取元素数量,`.subList()`用于获取子列表。我们可以结合这些方法,根据当前页码和每页数量来截取List中的部分...

    利用jQuery操作对象数组的实现代码

    尤其对于对象数组的操作,jQuery提供了一系列实用的方法,使得开发人员可以更加便捷地对数组中的对象进行遍历、过滤、查找和去重等操作。 首先,jQuery.each(obj, callback)方法是遍历数组或对象的关键工具,它允许...

    jQuery 对象中的类数组操作

    2. **get(index)**: 当不指定索引时,`get()`会返回一个JavaScript数组,包含整个jQuery对象中的所有元素。如果提供了索引,如`$(‘img[title]’).get(0)`,它将返回具有`title`属性的第一个`&lt;img&gt;`元素,这与`$(...

    JQuery使用数组遍历跳出each循环

    需要注意的是,由于jQuery的链式调用特性,`$.each()`方法总是返回原始jQuery对象,即使在回调函数中返回了`true`或`false`。因此,回调函数内的返回值仅用于控制循环行为,而无法直接传递到外部环境。 总结来说,...

    MVC3用Jquery Post Array 在后台Action获得集合

    本知识点主要探讨如何利用jQuery的`$.post`方法将JavaScript数组发送到后台Action,并在服务器端获取并处理这些数据。这通常涉及到JSON序列化、HTTP请求以及MVC模型绑定等技术。 首先,jQuery的`$.post`函数是用于...

    尚硅谷_教学课件_jQuery

    **jQuery 的核心特性** 1. **简洁的语法**:jQuery通过其特有的链式调用和选择器机制,使得编写DOM操作的代码变得简洁易读。 2. **高效的DOM操作**:jQuery提供了一套丰富的API来选取和操作DOM元素,如`$(selector)...

    2014-10-04-深入理解jQuery(1)——jQuery对象1

    jQuery对象通常包含一个类似数组的结构,用于存储匹配选择器的DOM元素。这种结构允许开发者使用索引来访问和操作这些元素,如`$elements[0]`。此外,jQuery对象还提供了`length`属性,表示存储的DOM元素数量。这样,...

    javascript 原生Dom对象和jQuery对象的联系和区别

    JavaScript中的DOM对象和jQuery对象是两种不同的数据结构,它们在处理网页元素时有着各自的特性和优缺点。了解它们之间的联系和区别对于JavaScript开发者来说至关重要,因为这有助于选择合适的工具进行网页交互。 ...

    《锋利的jQuery》

    转换前者通常通过将jQuery对象数组中的第一个元素赋值给一个变量来实现,因为jQuery对象本身是一个类数组对象,其内部存储了DOM元素的集合。例如,var domElement = $(“#myId”)[0];。而要将DOM对象转换为jQuery...

    jQery中类数组判断的实现原理及代码实现

    在jQuery中,经常会遇到需要处理类似数组的对象,比如`jQuery对象`就是一个典型的类数组对象。本文将深入探讨jQuery中类数组判断的实现原理,并通过代码实现来帮助理解这一概念。 首先,我们要明确什么是类数组对象...

    jQuery对象与DOM对象之间的相互转换

    1. **通过索引访问**:jQuery对象实际上是一个包含DOM元素的数组(或称为集合),因此可以通过索引访问其中的DOM元素。例如: ```javascript var $cr = $("#cr"); // jQuery对象 var cr = $cr[0]; // DOM对象,...

    浅谈jQuery操作类数组的工具方法

    当使用jQuery的`$()`函数时,通常会返回一个JQuery对象,这个对象可以被视为“类数组”对象,因为它具有数组的一些特性,但并非真正的Array。本文将深入探讨jQuery操作类数组对象的方法。 首先,`length`属性是一个...

    js jquery数组介绍

    首先,关于JavaScript(简称JS)和jQuery数组的基础知识,我们需要了解数组是JS中一种特殊的对象,用于存储有序的数据集合。在jQuery中,数组的处理方式和原生JS大致相同,但jQuery提供了一些方便的方法来处理数组。...

    jQuery $.each遍历对象、数组用法实例

    jQuery的$.each方法是用于遍历对象或数组的一个强大工具,它提供了灵活的方式来处理数据集合中的每个元素或属性。在JavaScript中,遍历通常是为了执行某种操作,如修改、检查或计算。$.each方法有两种主要的用法,一...

    JS对象转换为Jquery对象示例

    jQuery对象与JavaScript对象虽然在某些方面有相似性,但它们各自具有不同的特性。jQuery对象是由jQuery库创建的,包含了DOM元素的集合,并且能够直接调用jQuery提供的各种方法,比如选择、操作DOM、事件处理等。 ...

Global site tag (gtag.js) - Google Analytics