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;
    }

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

    如果觉得本文不错,请点击右下方【推荐】!
    如果本文对您有所帮助,可以打赏一下作者,给作者一点鼓励~~~~
  • 相关阅读:
    iframe跨页面调用函数
    $.extend()
    tab标签 插件 by 腾讯 jianminlu
    click事件多次触发 jQuery
    vertical-align
    display:inline-block
    在父页面访问iframe的东西
    2019牛客多校第三场
    2019HDU多校第一场
    2019江苏省赛
  • 原文地址:https://www.cnblogs.com/chuaWeb/p/jQuery-1-9-1-frame1.html
Copyright © 2011-2022 走看看