zoukankan      html  css  js  c++  java
  • jQuery-1.9.1源码分析系列(一)整体架构

    不废话,直接上关键。这个系列中有好些直接借用别人的资料,我将他们整合在自认为比较合理的地方。所以在此先谢谢那些前辈。

    注意:后续系列中jQuery实例多用$(...)来表示

    1.    初始化与链式调用基础


    jQuery之所以能够链式调用在于每次调用返回来jQuery本身。实现关键代码如下。

    jQuery = function(selector,context){
      return new jQuery.fn.init(selector,context,rootjQuery);
    }
    ...
    rootjQuery = jQuery(document);
    ...
    jQuery.fn = jQuery.prototype = {
      constructor: jQuery,
      init: function(selector,context,rootjQuery){
        ...
        return this;     ... } } ... jQuery.fn.init.prototype = jQuery.fn; ... window.jQuery = window.$ = jQuery;

      

    需要有几个理解

    a.    new的深度理解


     var obj = new Base();

    这样代码的结果是什么,我们在Javascript引擎中看到的对象模型是:

     

    new操作符具体干了什么呢?其实很简单,就干了三件事情。

    var obj = {};
    
    obj.__proto__ = Base.prototype;
    
    Base.call(obj);

    第一行,我们创建了一个空对象obj;

    第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象;

    第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id(name,根据浏览器决定,chrome是name属性)成员变量,这个成员变量的值是”Base”。

     

    Base函数返回的结果会导致obj的结果不同。

    举例(chrome下):

    function Base(){
      this.name = “test”;
      this.a = “f”;
      return result;
    }

    1)     根据new的原理,如果没有返回值或返回值为数字或字符串或布尔类型,即result为null/number/string/bool,则new Base()返回的结果是本身,为

    Base {name: "test", a: "f"}

    2)     如果返回值为对象(数组或普通对象)或函数,则返回的对象或函数替换了Base本身;

    拓展:

           new Base() == Base () 返回的结果为false

        例如当result为[]的时候,new Base()返回结果和Base()返回结果的都是[],但实际上他们并不相等 , Javascript  对于 Object 和 Function 的比较是基于引用的.

    Var m = [],t = []; m == t;//false,并不是同一个引用

    Var m = t = []; m == t;//true

    b.    jQuery中jQuery.fn为什么表现为数组


    jQuery将对象模拟成了数组,而如何让一个对象模拟成数组,jQuery给对象加上了以下几个属性:

    {
      length: 0,
      push: [].push,
      sort: [].sort,
      splice: [].splice
    },

    不同的是chrome在给对象添加了length和splice后真的转化成了数组,如$()结果是[],而ie没有转化$()结果是{}。但是无所谓,他们都可以使用length等属性,不影响后续使用。如果$(…)有搜索结果,jQuery会把结果拼接成数组返回,这样jQuery的返回结果看起来总是数组。

    总结


      由上面的分析可知jQuery.fn.init.prototype = jQuery.fn目的就是将jQuery.fn上的所有属性都挂在jQuery实例$(...)上,使得实例拥有很多jQuery.fn上定义的函数。比如jQuery.fn.extend函数,实例就可以直接使用:$(...).extend({"name": "chua"})。

      由于每次都是一个新的实例new jQuery.fn.init(selector,context,rootjQuery),所以各个实例是独立的。而jQuery全局的属性直接挂在jQuery上,比如jQuery.extend,这个和jQuery.fn.extend不一样了,因为jQuery.extend是全局的,比如jQuery.extend({"test": "chua"})你可以随时通过jQuery.test就把值给取出来了,而jQuery实例则需要保证同一个实例的情况下才能取到值。比如var ps = $("p").extend({"test": "chua"}),通过ps.test能够取到值,但是你使用$("p").test是取不到的。因为你使用$(...)又新建了一个实例。

      至于jQuery的链式调用很好理解,源码初始化的时候返回了jQuery对象本身:

    init: function(selector,context,rootjQuery){
      ...
      return this;
    }

      这一节先到这里,待续……

    如果觉得本文不错,请点击右下方【推荐】!
    如果本文对您有所帮助,可以打赏一下作者,给作者一点鼓励~~~~
  • 相关阅读:
    我要好offer之 二叉树大总结
    我要好offer之 字符串相关大总结
    楼层扔鸡蛋问题[转]
    Linux System Programming 学习笔记(十一) 时间
    Linux System Programming 学习笔记(十) 信号
    Linux System Programming 学习笔记(九) 内存管理
    Linux System Programming 学习笔记(八) 文件和目录管理
    Linux System Programming 学习笔记(七) 线程
    Linux System Programming 学习笔记(六) 进程调度
    APUE 学习笔记(十一) 网络IPC:套接字
  • 原文地址:https://www.cnblogs.com/chuaWeb/p/jQuery-1-9-1-frame1.html
Copyright © 2011-2022 走看看