码迷,mamicode.com
首页 > Web开发 > 详细

jQuery-1.9.1源码分析系列(一)整体架构

时间:2015-11-03 17:13:57      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:

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

注意:后续系列中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;

    }

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

jQuery-1.9.1源码分析系列(一)整体架构

标签:

原文地址:http://www.cnblogs.com/chuaWeb/p/jQuery-1-9-1-frame1.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!