欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

jQuery 源码解析(七) jQuery对象和DOM对象的互相转换

程序员文章站 2023-11-19 19:09:46
jQuery对象是一个类数组对象,它保存的是对应的DOM的引用,我们可以直接用[]获取某个索引内的DOM节点,也可以用get方法获取某个索引内的DOM节点,还可以用toArray()方法把jQuery对象一次性转换成一个数组,例如: 将DOM对象转换为jQuery对象就更方便了,直接放到jQuery ......

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

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>document</title>
    <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <script>
        var jobject = $('p');
        console.log(jobject[0].innerhtml)            //输出:1
        console.log(jobject[1].innerhtml)            //输出:2
        console.log(jobject.get(2).innerhtml)        //输出:3
        console.log(jobject.toarray())               //输出:array(3) [ p, p, p ]     ;每个元素都是一个dom节点,等于对应的p元素
    </script>
</body>
</html>

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

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>document</title>
    <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <script>
        var p         =     document.getelementsbytagname('p'),        
            result    =    [];                                        
        for(let i = 0;i<p.length;i++)        result.push(i)        //getelementsbytagname获取的是htmlcollection对象,也是个类数组,我们把它转换为数组格式

        console.log( $(p) instanceof $ )                        //输出true        ;表示$(p)是一个jquery对象
        console.log( $(p).size() )                              //输出:3            ;因为p内有3个dom元素

        console.log( $(p[0]) instanceof $ )                     //输出true        ;表示$(p)是一个jquery对象
        console.log( $(p[0]).size() )                           //输出:1            ;因为我们只传入一个p[0],只有一个dom节点
    </script>
</body>
</html>

输出如下:

jQuery 源码解析(七) jQuery对象和DOM对象的互相转换

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

 

源码分析

writer by:大沙漠 qq:22969969


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

init: function( selector, context, rootjquery ) {
  /*略*/
  // handle $(domelement)
  if ( selector.nodetype ) {                  //selector有属性nodetype,则认为selector是dom元素,例如:$(document.getelementbyid('d'))
    this.context = this[0] = selector;            //保存该dom节点的引用
    this.length = 1;                              //设置length属性为1
    return this;                                  //返回this,以支持链式操作
  }

  /*略*/

  return jquery.makearray( selector, this );  //这里是最后的逻辑,如果selector是数组或伪数组
},

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

  makearray: function( array, results ) {     //将一个类数组对象转换为真正的数组
    var ret = results || [];                    //如果results不存在则修正为空数组,初始化jquery执行到这里时这里的result等于jquery对象,也就是上面传进来的this

    if ( array != null ) {                      //过滤参数array是null、undefined的情况。
      // the window, strings (and functions) also have 'length'
      // tweaked logic slightly to handle blackberry 4.7 regexp issues #6930
      var type = jquery.type( array );

      if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jquery.iswindow( array ) ) {    //如果array没有属性length 或者 参数array是字符串,或者是函数,或者是正则,或者是window对象
        push.call( ret, array );                                                                                                        //认为参数array不是数组,也不是类数组对象,调用数组方法push()把该参数插入返回值ret的末尾。
      } else {
        jquery.merge( ret, array );           //否则认为参数array是数组或类数组对象,调用方法jquery.merge()把该参数合并到返回值ret中
      }
    }

    return ret;
  },

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

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

jquery.fn = jquery.prototype = {  //重写jqueyr.fn
  /*略*/
  toarray: function() {               //将当前jquery对象转换为真正的数组,转换后的数组包含了所有元素。
    return slice.call( this, 0 );
  },
  get: function( num ) {              //返回当前jquery 对象中指定位置的元素或包含了全部元素的数组,
    return num == null ?

      // return a 'clean' array
      this.toarray() :

      // return just the object
      ( num < 0 ? this[ this.length + num ] : this[ num ] );      //直接返回this[num],也就是和我们用[]是一样的,只是封装了一下
  },
  /*略*/
}

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