• jQuery的类数组对象结构(转)


    原文:http://www.imooc.com/code/3248

    为什么是类数组对象呢?

    很多人迷惑的jQuery为什么能像数组一样操作,通过对象get方法或者直接通过下标0索引就能转成DOM对象。

    首先我们看jQuery的入口都是统一的$, 通过传递参数的不同,实现了9种方法的重载:

    1. jQuery([selector,[context]])
    2. jQuery(element)
    3. jQuery(elementArray)
    4. jQuery(object)
    5. jQuery(jQuery object)
    6. jQuery(html,[ownerDocument])
    7. jQuery(html,[attributes])
    8. jQuery()
    9. jQuery(callback)

    9种用法整体来说可以分三大块:选择器、dom的处理、dom加载。
    换句话说jQuery就是为了获取DOM、操作DOM而存在的!所以为了更方便这些操作,让节点与实例对象通过一个桥梁给关联起来,jQuery内部就采用了一种叫“类数组对象”的方式作为存储结构,所以我们即可以像对象一样处理jQuery操作,也能像数组一样可以使用push、pop、shift、unshift、sort、each、map等类数组的方法操作jQuery对象了。

    jQuery对象可用数组下标索引是什么原理?

    通过$(".Class")构建的对象结构如下所示:


                       
    整个结构很明了,通过对象键值对的关系保存着属性,原型保存着方法。我们来简单的模拟一个这样的数据结构:见下面的代码

    <!DOCTYPE HTML>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="http://img.mukewang.com/down/540812440001e40e00000000.js" type="text/javascript"></script>
    <style type="text/css">
        div{
            width: 30px;
            height: 10px;
            float:left;
        }
    </style>
    <title>无标题文档</title>
    </head>
    <body>
    
    <button id="test1">jQuey[0]</button>
    <button id="test2">jQuey.get</button>
    <button id="test3">aQuery[0]</button>
    <button id="test4">aQuery.get</button>
    
    <p id="book">book</p>
    
    <div id="show1"></div>
    <div id="show2"></div>
    <div id="show3"></div>
    <div id="show4"></div>
    
    <script type="text/javascript">
    
    var aQuery = function(selector) {
        //强制为对象
        if (!(this instanceof aQuery)) {
            return new aQuery(selector);
        }
        var elem = document.getElementById(/[^#].*/.exec(selector)[0]);
        this.length = 1;
        this[0] = elem;
        this.context = document;
        this.selector = selector;
        this.get = function(num) {
            return this[num];
        }
        return this;
    }
    
    //结果是一个dom元素,可以把代码放到Google Chrome下运行
    //按F12通过调试命令 console.log() 打印出对象
    $("#test1").click(function() {
        $('#show1').append($('#book')[0])
    })
    
    $("#test2").click(function() {    
        $('#show2').append($('#book').get(0))
    })
    
    $("#test3").click(function() {
        $('#show3').append(aQuery("#book")[0])
    })
    
    $("#test4").click(function() {
        $('#show4').append(aQuery("#book").get(0))
    })
    
    
    </script>
    
    </body>
    </html>

    以上是模拟jQuery的对象结构,通过aQuery方法抽象出了对象创建的具体过程,这也是软件工程领域中的广为人知的设计模式-工厂方法。

    jQuery的无new构建原理

    函数aQuery()内部首先保证了必须是通过new操作符构建。这样就能保证当前构建的是一个带有this的实例对象,既然是对象我们可以把所有的属性与方法作为对象的keyvalue的方式给映射到this上,所以如上结构就可以模拟出jQuery的这样的操作了,即可通过索引取值,也可以链式方法取值,但是这样的结构是有很大的缺陷的,每次调用ajQuery方法等于是创建了一个新的实例,那么类似get方法就要在每一个实例上重新创建一遍,性能就大打折扣,所以jQuery在结构上的优化不仅仅只是我们看到的,除了实现类数组结构、方法的原型共享,而且还实现方法的静态与实例的共存,这是我们之后将会重点分析的。

  • 相关阅读:
    国王游戏
    从2014到2015,还有什么?
    【转载】别把自己推到了墙角
    IE9+浏览器input文本框/密码框后面的小叉子/小眼睛清除
    ajax开发模拟后端数据接口
    谈谈JavaScript事件
    也说border-box盒模型
    极其简单的使用基于gulp和sass前端工作流
    如何使用javascript书写递归函数
    Git基本命令和GitFlow工作流
  • 原文地址:https://www.cnblogs.com/ajianbeyourself/p/5701501.html
Copyright © 2020-2023  润新知