• 读jQuery之一(对象的组成)


    首次接触jQuery是在2008年,上地的一家小公司。当时的版本是1.1,在此之前我仅接触过Prototype.js。对于jQuery的写法甚是困惑,尤其在使用Prototype的$后,一度不能理解jQuery的$。对于现在前端同学来说,可能第一个接触的就是jQuery了,他们会觉得很习惯,很自然。

     

    至今电脑里还存放着当时的API文档,发个图感叹下

     

    在这段时间内,我的入门老师是墨墨,其实至今他仍然是我敬仰的同事之一。他的编程造诣很高,相信早已突破了编程语言的限制。在大家都在使用Prototype.js的时候,在jQuery尚未在国内流行的时候,他就已经把jQuery引入到项目中了。

    言归正传吧,目前的jQuery版本已经到了1.6.1。从当时的2000行左右膨胀到了9000行。相信不久就会突破1w行。对于一些简单网页来说引入一个jQuery已经不再那么轻量了。这里的研读的是1.6.1这个版本,我会边读边写,最后会写出一个1000行左右的“迷你jQuery”。

     

    以下是jQuery 1.6.1 代码片段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var jQuery = function( selector, context ) {
            // The jQuery object is actually just the init constructor 'enhanced'
            return new jQuery.fn.init( selector, context, rootjQuery );
        },
        ...
        class2type = {};
         
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function(selector, context, rootjQuery){
        }
    }
     
    // Give the init function the jQuery prototype for later instantiation
    jQuery.fn.init.prototype = jQuery.fn;

     

    初看上去像是在用 原型方式 在写一个类jQuery(别名$),但实际我们使用时是函数调用$("#id"),却不是new $("#id")。
    标识符 jQuery是一个function,其内new了一个function init的实例,然后返回。至此我们知道其真正的构造器是jQuery.fn.init。jQuery写的实在诡异,它把init又挂在了jQuery的prototype上,阅读起来有些绕人。

     

    jQuery.fn.init.prototype = jQuery.fn; 是关键的一句。该句把function jQuery的原型赋值给了function init的原型。当调用$("#id")时返回的对象组成包括两个部分。
    1,由function init中this带的(如this.context);
    2,由function jQuery的prototype带的(如this.size/this.toArray);

     

    模仿jQuery写一个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    // zchain-0.1.js
    function $(selector){
        return new $.prototype.init(selector);
    }
    $.prototype={
        init:function(selector){
            if(selector === undefined){
                this.length = 0;
                return this;
            }
            if(selector.nodeType==1){
                this[0] = selector;
            }else{
                this[0]=document.getElementById(selector);
            }
            this.length=1;
        },
        css:function(name,value){
            this[0].style[name] = value;
            return this;//链式调用
        },
        hide:function(){
            var self=this;
            setTimeout(function(){
                self[0].style.display="none";
            },3000);
            return this;//链式调用
        }
    }
    $.prototype.init.prototype=$.prototype;

    简单起见,这里选择器只传html element或元素id(后续会增强,但不实现全部css selector),this上挂了length属性,赋值为1。

    当我们调用时

    1
    2
    var obj = $();  
    console.dir(obj);

    $()实际没有什么意义,只是为了测试调用后obj的组成。firebug控制台输出如下:
    length:0;
    init:function
    attr:function
    hide:function


    即obj对象是由function init中this及function $.prototype组成的。

    再看下$.prototype上的方法,我只添加了css和hide方法,这两个方法的实现也是极其简陋的。

    1
    2
    3
    4
    5
    <div id='content'>3 seconds later I will hide.</div>
    <script type="text/javascript">
        $("content").css("color","red").hide();
    </script>

    先调用css设置了字体颜色为红色,3秒后隐藏了。

     

    总结下:
    jQuery对象指的是jQuery.prototype.init的实例,简单的说就是new jQuery.prototype.init。这里jQuery.prototype.init的类型是function,可以看成是一个类。

    jQuery对象由以下部分组成:

    1. 挂在jQuery.prototype.init中的this上的属性或方法。
    2. 挂在jQuery.prototype.init.prototype上的属性或方法。
    3. 因为把jQuery.prototype赋值给了jQuery.prototype.init.prototype,所以挂在jQuery.prototype上的属性和方法也是jQuery对象的一部分。
    4. 通过jQuery.fn.extend({...})方式扩展的属性或方法(后续提到)。

     

  • 相关阅读:
    2021/9/20 开始排序算法
    快速排序(自己版本)
    2021/9/17(栈实现+中后缀表达式求值)
    2021/9/18+19(中缀转后缀 + 递归 迷宫 + 八皇后)
    20212021/9/13 稀疏数组
    2021/9/12 线性表之ArrayList
    开发环境重整
    Nginx入门
    《财富的帝国》读书笔记
    Linux入门
  • 原文地址:https://www.cnblogs.com/xiaohong/p/4460262.html
Copyright © 2020-2023  润新知