- 浏览: 323268 次
- 性别:
- 来自: 南昌
文章分类
最新评论
-
j_bird:
你好,想探讨下滑动窗口是怎么计算的,一条群发短信发出去,滑动窗 ...
协议研发 中移动CMPP2.0协议API -
andyliulin:
楼主,现在的magicode 生成器工具的 官网,http: ...
Mgicode 生成器正式发布 -
huazai_wow:
楼主 你只是分析了 在jquery 中 有使用到 jQu ...
jquery event trigger 分析 -
dengkanghua:
CMPP2.0中出现流量控制错误是什么引起的。有什么解决办法吗 ...
协议研发 中移动CMPP2.0协议API -
JohnHust:
[flash=200,200][/flash][url][/u ...
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.validate.js的基本用法入门
2011-03-10 22:35 2884[转载]jquery.validate.js的基本用法入门 j ... -
使用javascript动态创建SVG对象的问题
2011-01-11 17:18 4745无沙备忘录系列 -平时的一些研究,有时也会颇费功夫,然 ... -
evaluate mxGraph
2010-06-10 16:09 1726To evaluate mxGraph: - Navigate ... -
js中的prototype与constructor
2010-06-09 10:53 2923并且每个函数都有一个默认的prototype属性。 如果这个函 ... -
Jquery1.2.6 源码分析
2008-08-29 00:13 14154jQuery是一个非常优秀的J ... -
jquery fx分析
2008-08-28 19:37 63178 FX分析 prk/彭仁夔 ... -
jqueyr fx源码(修改)
2008-08-28 19:33 2673/* * author:prk date:2008-08-0 ... -
jquery.ajax
2008-08-27 16:50 81157.2 jquery.ajax ... -
jquery event domready
2008-08-26 17:39 41416.3 domReady的处理 ... -
jquery event trigger 分析
2008-08-26 17:37 113786.2.2 trigger ... -
jquery event addEvent 分析
2008-08-26 17:36 111976.2 事件的处理 ... -
jquery event 封装的源源分析
2008-08-26 17:35 46046.Event分析 ... -
jquery position
2008-08-25 16:34 87825.2.3 position ... -
jquery wrap
2008-08-25 08:12 44805.3.5 wrap ... -
jquery element content
2008-08-25 08:11 43495.4dom元素的内容 ... -
jquery class
2008-08-22 23:18 53715.1.2 Class prk/彭仁夔 2008- ... -
jquery attr
2008-08-22 23:16 76175 DOM元素 prk/彭仁夔 ... -
jquery Selector (修改)
2008-08-21 17:10 3098/** * author:prk * date:2008- ... -
CSS selector (jquery的源码分析,修改)
2008-08-21 17:09 44193.3、采用CSS方式查找Dom节点 ... -
如何找到Dom元素
2008-08-20 22:10 28323、如何找到Dom元素 ...
相关推荐
本主题将深入探讨如何使用jQuery库来实现数组、集合(如Java中的List)以及JSON类型的分页功能。jQuery作为一款强大的JavaScript库,简化了DOM操作,使得分页功能的实现变得更加简便。 首先,我们要理解分页的基本...
在本文中,我们将深入探讨jQuery的DOM对象事件处理、隐藏显示功能以及如何操作对象数组。jQuery作为一个广泛使用的JavaScript库,它简化了HTML文档遍历、事件处理、动画和Ajax交互,使得Web开发更加便捷。 首先,让...
集合List的分页与数组类似,只是需要考虑List的特性和API。在Java中,List接口提供了如`.size()`用于获取元素数量,`.subList()`用于获取子列表。我们可以结合这些方法,根据当前页码和每页数量来截取List中的部分...
尤其对于对象数组的操作,jQuery提供了一系列实用的方法,使得开发人员可以更加便捷地对数组中的对象进行遍历、过滤、查找和去重等操作。 首先,jQuery.each(obj, callback)方法是遍历数组或对象的关键工具,它允许...
2. **get(index)**: 当不指定索引时,`get()`会返回一个JavaScript数组,包含整个jQuery对象中的所有元素。如果提供了索引,如`$(‘img[title]’).get(0)`,它将返回具有`title`属性的第一个`<img>`元素,这与`$(...
需要注意的是,由于jQuery的链式调用特性,`$.each()`方法总是返回原始jQuery对象,即使在回调函数中返回了`true`或`false`。因此,回调函数内的返回值仅用于控制循环行为,而无法直接传递到外部环境。 总结来说,...
本知识点主要探讨如何利用jQuery的`$.post`方法将JavaScript数组发送到后台Action,并在服务器端获取并处理这些数据。这通常涉及到JSON序列化、HTTP请求以及MVC模型绑定等技术。 首先,jQuery的`$.post`函数是用于...
**jQuery 的核心特性** 1. **简洁的语法**:jQuery通过其特有的链式调用和选择器机制,使得编写DOM操作的代码变得简洁易读。 2. **高效的DOM操作**:jQuery提供了一套丰富的API来选取和操作DOM元素,如`$(selector)...
jQuery对象通常包含一个类似数组的结构,用于存储匹配选择器的DOM元素。这种结构允许开发者使用索引来访问和操作这些元素,如`$elements[0]`。此外,jQuery对象还提供了`length`属性,表示存储的DOM元素数量。这样,...
JavaScript中的DOM对象和jQuery对象是两种不同的数据结构,它们在处理网页元素时有着各自的特性和优缺点。了解它们之间的联系和区别对于JavaScript开发者来说至关重要,因为这有助于选择合适的工具进行网页交互。 ...
转换前者通常通过将jQuery对象数组中的第一个元素赋值给一个变量来实现,因为jQuery对象本身是一个类数组对象,其内部存储了DOM元素的集合。例如,var domElement = $(“#myId”)[0];。而要将DOM对象转换为jQuery...
在jQuery中,经常会遇到需要处理类似数组的对象,比如`jQuery对象`就是一个典型的类数组对象。本文将深入探讨jQuery中类数组判断的实现原理,并通过代码实现来帮助理解这一概念。 首先,我们要明确什么是类数组对象...
1. **通过索引访问**:jQuery对象实际上是一个包含DOM元素的数组(或称为集合),因此可以通过索引访问其中的DOM元素。例如: ```javascript var $cr = $("#cr"); // jQuery对象 var cr = $cr[0]; // DOM对象,...
当使用jQuery的`$()`函数时,通常会返回一个JQuery对象,这个对象可以被视为“类数组”对象,因为它具有数组的一些特性,但并非真正的Array。本文将深入探讨jQuery操作类数组对象的方法。 首先,`length`属性是一个...
首先,关于JavaScript(简称JS)和jQuery数组的基础知识,我们需要了解数组是JS中一种特殊的对象,用于存储有序的数据集合。在jQuery中,数组的处理方式和原生JS大致相同,但jQuery提供了一些方便的方法来处理数组。...
jQuery的$.each方法是用于遍历对象或数组的一个强大工具,它提供了灵活的方式来处理数据集合中的每个元素或属性。在JavaScript中,遍历通常是为了执行某种操作,如修改、检查或计算。$.each方法有两种主要的用法,一...
jQuery对象与JavaScript对象虽然在某些方面有相似性,但它们各自具有不同的特性。jQuery对象是由jQuery库创建的,包含了DOM元素的集合,并且能够直接调用jQuery提供的各种方法,比如选择、操作DOM、事件处理等。 ...