jQuery对象是一个类数组对象,它保存的是对应的DOM的引用,我们可以直接用[]获取某个索引内的DOM节点,也可以用get方法获取某个索引内的DOM节点,还可以用toArray()方法把jQuery对象一次性转换成一个数组,例如:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
  7. </head>
  8. <body>
  9. <p>1</p>
  10. <p>2</p>
  11. <p>3</p>
  12. <script>
  13. var jObject = $('p');
  14. console.log(jObject[0].innerHTML) //输出:1
  15. console.log(jObject[1].innerHTML) //输出:2
  16. console.log(jObject.get(2).innerHTML) //输出:3
  17. console.log(jObject.toArray()) //输出:Array(3) [ p, p, p ] ;每个元素都是一个DOM节点,等于对应的p元素
  18. </script>
  19. </body>
  20. </html>

将DOM对象转换为jQuery对象就更方便了,直接放到jQuery的构造器内即可,如下:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
  7. </head>
  8. <body>
  9. <p>1</p>
  10. <p>2</p>
  11. <p>3</p>
  12. <script>
  13. var p = document.getElementsByTagName('p'),
  14. result = [];
  15. for(let i = 0;i<p.length;i++) result.push(i) //getElementsByTagName获取的是HTMLCollection对象,也是个类数组,我们把它转换为数组格式
  16.  
  17. console.log( $(p) instanceof $ ) //输出true ;表示$(p)是一个jQuery对象
  18. console.log( $(p).size() ) //输出:3 ;因为p内有3个DOM元素
  19.  
  20. console.log( $(p[0]) instanceof $ ) //输出true ;表示$(p)是一个jQuery对象
  21. console.log( $(p[0]).size() ) //输出:1 ;因为我们只传入一个p[0],只有一个DOM节点
  22. </script>
  23. </body>
  24. </html>

输出如下:

原因在代码里注释得挺详细了,嗯,就这样

源码分析

writer by:大沙漠 QQ:22969969


DOM转换成jQuery对象都是在jQuery内部的init()函数内实现的,如下:

  1. init: function( selector, context, rootjQuery ) {
  2. /*略*/
  3. // Handle $(DOMElement)
  4. if ( selector.nodeType ) { //selector有属性nodeType,则认为selector是DOM元素,例如:$(document.getELementById('d'))
  5. this.context = this[0] = selector; //保存该DOM节点的引用
  6. this.length = 1; //设置length属性为1
  7. return this; //返回this,以支持链式操作
  8. }
  9.  
  10. /*略*/
  11.  
  12. return jQuery.makeArray( selector, this ); //这里是最后的逻辑,如果selector是数组或伪数组
  13. },

makeArray是jQuery内部的一个函数,用于把一个类数组转换成真正的数据,如下:

  1. makeArray: function( array, results ) { //将一个类数组对象转换为真正的数组
  2. var ret = results || []; //如果results不存在则修正为空数组,初始化jQuery执行到这里时这里的result等于jQuery对象,也就是上面传进来的this
  3.  
  4. if ( array != null ) { //过滤参数array是null、undefined的情况。
  5. // The window, strings (and functions) also have 'length'
  6. // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
  7. var type = jQuery.type( array );
  8.  
  9. if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { //如果array没有属性length 或者 参数array是字符串,或者是函数,或者是正则,或者是Window对象
  10. push.call( ret, array ); //认为参数array不是数组,也不是类数组对象,调用数组方法push()把该参数插入返回值ret的末尾。
  11. } else {
  12. jQuery.merge( ret, array ); //否则认为参数array是数组或类数组对象,调用方法jQuery.merge()把该参数合并到返回值ret中
  13. }
  14. }
  15.  
  16. return ret;
  17. },

最后返回该数组,因为我们在第二个参数传递了this,因此makeArray最后会返回this

对于jQuery对象转换为DOM对象来说,由于jQuery本身就是个类数组对象,因此,我们可以直接用[]获取索引,对于get和toArray方法来说,这些操作定义在jQuery的原型上,也就是jQuery.fn上的,如下:

  1. jQuery.fn = jQuery.prototype = { //重写jQueyr.fn
  2. /*略*/
  3. toArray: function() { //将当前jQuery对象转换为真正的数组,转换后的数组包含了所有元素。
  4. return slice.call( this, 0 );
  5. },
  6. get: function( num ) { //返回当前jQuery 对象中指定位置的元素或包含了全部元素的数组,
  7. return num == null ?
  8.  
  9. // Return a 'clean' array
  10. this.toArray() :
  11.  
  12. // Return just the object
  13. ( num < 0 ? this[ this.length + num ] : this[ num ] ); //直接返回this[num],也就是和我们用[]是一样的,只是封装了一下
  14. },
  15. /*略*/
  16. }

我们可以看到对于get来说,就是直接从this[]上获取的,而toArray则调用了数组了slice方法,将类数组转换成真实的数组

jQuery 源码解析(七) jQuery对象和DOM对象的互相转换的更多相关文章

  1. jquery源码解析:jQuery静态属性对象support详解

    jQuery.support是用功能检测的方法来检测浏览器是否支持某些功能.针对jQuery内部使用. 我们先来看一些源码: jQuery.support = (function( support ) ...

  2. 三.jQuery源码解析之jQuery的框架图

    这张图片是对jQuery源码截图,一点一点拼出来的. 现在根据这张图片来对jQuery框架做一些说明. 一.16~9404行可以发现,最外层是一个自调用函数.当jQuery初始化时,这个自调用函数包含 ...

  3. jquery源码解析:jQuery数据缓存机制详解2

    上一课主要讲了jQuery中的缓存机制Data构造方法的源码解析,这一课主要讲jQuery是如何利用Data对象实现有关缓存机制的静态方法和实例方法的.我们接下来,来看这几个静态方法和实例方法的源码解 ...

  4. jquery源码解析:jQuery数据缓存机制详解1

    jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...

  5. jquery源码解析:jQuery工具方法when详解

    我们先来看when方法是如何使用的: var cb = $.when();   //when方法也是返回一个延迟对象,源码是return deferred.promise();返回的延迟对象不能修改状 ...

  6. jquery源码解析:jQuery工具方法Callbacks详解

    我们首先来讲下Callbacks是如何使用的:第一个例子 function a(){} function b(){} var cb = $.Callbacks(); cb.add(a); cb.add ...

  7. jquery源码解析:jQuery队列操作queue方法实现的原理

    我们先来看一下jQuery中有关队列操作的方法集: 从上图可以看出,既有静态方法,又有实例方法.queue方法,相当于数组中的push操作.dequeue相当于数组的shift操作.举个例子: fun ...

  8. jquery源码解析:val方法和valHooks对象详解

    这一课,我们将讲解val方法,以及对value属性的兼容性处理,jQuery中通过valHooks对象来处理. 首先,我们先来看下val方法的使用: $("#input1").va ...

  9. jquery源码解析:jQuery延迟对象Deferred(工具方法)详解2

    请接着上一课继续看. $.Deferred()方法中,有两个对象,一个是deferred对象,一个是promise对象. promise对象有以下几个方法:state,always,then,prom ...

随机推荐

  1. C# download big file

    I had validated this.To download SSMS which is more than 500M+ static void Main(string[] args) { str ...

  2. 自从用python写了个自动弹幕脚本后,各大主播都来找我,净赚十万!

    大家好,今天又给大家带来了Python爬虫的分享,今天我们继续上次的问题,继续来研究一下虎牙平台的爬虫. 起因 写完上次的代码,我冒出有一个很有趣的想法,就是,我们可以使用selenium来完成虎牙自 ...

  3. 如何使用npm的部分用法以及npm被墙的解决方法

    我们要明白我们使用的npm就是node中自带的包(模块)管理工具:借助NPM可以帮助我们快速安和管理依赖包,使Node与第三方模块之间形成了一个良好的生态系统. 我们可以直接输入npm,查看帮助引导: ...

  4. PHP+Swoole 作为网络通信框架

    PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列, ...

  5. sed文本处理

    1.基本概述 sed是一个流编辑器, 非交互式的编辑器,它一次处理一行内容. 处理时,把当前处理的行存储在临时缓冲区中,称* 为"模式空间"(pattern space) 接着用 ...

  6. 关于解决Xcode更新7.3之后插件不能用的问题

    Xcode更新7.3之后,之前安装好好的插件现在突然间不能用了(如:我在写背景颜色或者字体颜色的时候,突然间不出来联想的图案来供我选择了),解决这个问题的步骤如下: 1.打开电脑终端,把default ...

  7. Kotlin介绍(非原创)

    文章大纲 一.Kotlin简介二.Kotlin相比Java优势三.Kotlin与Java混合使用四.参考文章   一.Kotlin简介 1. 什么是Kotlin 安卓和Java,前者是最受欢迎的移动开 ...

  8. oracle 死锁 锁

    [zhuan]今天看群里在讨论数据库死锁的问题,也一起研究了下,查了些资料在这里总结下. 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...

  9. configure.ac文件和Makefile.am文件 编译

    在编译安装openvpn 项目时遇到,其编译过程如下:生成 configure 可执行文件 make && make install ; . aclocal . autoconf . ...

  10. gevent实现协程

    gevent的好处:能够自动识别程序中的耗时操作,在耗时的时候自动切换到其他任务 # gevent的好处:能够自动识别程序中的耗时操作,在耗时的时候自动切换到其他任务 from gevent impo ...