“Jquery对象”的本质和构造思路

1. 根本没有"Jquery对象"

我把jqurey对象加上了双引号,因为在理论上jquery根本不存在“jquery对象”东西,如果从面向对象的角度来说,对象都是经由一个类new出来的,而jquery最直观的一点就是:jquery并没有经过new这个过程(当然js也可以使用特殊的手段不经由new关键字而生成一个对象,可是jquery也没有经过这个方式构建出来),jquery更多的只是一个壳而已,其实在使用$操作对象的时候,借由jquery这个壳来生成一个对象而已,之所以称为jquery对象,也许是因为比较好理解而已。如果真的要说对象,不如说是jquery原型里面的init构造函数生成的对象,叫做"init对象"还更贴切,而且这个对象的原型是是jquery的原型,这个理解起来确实挺绕的。以后文章如果提到jquery对象的时候,希望可以马上就在脑海里直接想起jquery.fn.init构造的对象。

这里可以看看从jquery生成方式上入手来看看。

$()之后到底做了什么事情呢?其实就是向jquery的原型对象里面“填充”dom对象而已。当使用$()的时候,jquery框架就会new出一个对象,

这个对象的构造函数就是jquery的原型对象的init函数,这个init函数的原型对象指向的也是jquery的原型对象,这样做的好处就是既可以访问到init函数里面的this属性,也可以访问到jquery原型对象的属性。

2. 拆解Jquery对象

为了加深自己的理解,其实可以把整个jquery拆解出来,使用另外一种不是那么紧凑的方式来实现。这样就可以不受jquery框架的干扰,然后厘清上面所记录的内容了。

?
01
02
03
04
05
06
07
08
09
10
11
12
var wraper = function (){
     return new o.init();
};
var o = {
     init: function (){
         this .length = 50;
     },
     version: "1.0" ,
     size: function (){ return this .length}
}
o.init.prototype = o;
alert(wraper().length);

 

wrapper函数的主要作用就是返回一个对象,而这个对象其实也不是什么特别的东西,也是一个构造函数而已,其实也就是类似于function init(){},这样的话,当我们new 出它的实例的时候,得到的也就是一个init()构造函数实例化出来的对象,这个对象就应该有上面的length属性,可是这样其实是不够的,如果你既想要init对象里面的length属性,也要o对象里面的length属性的话,那要怎么办?这个问题解决了,那么jquery的构造思路大概也就清楚了。在上面的片段中有一行是这样的:o.init.prototype = o,这行代码直接把o.init.prototype的原型对象的引用直接指向了o对象,那么从init构造函数new出来的实例就拥有了o的属性和方法了,这样就达到上面要的目的,既可以访问init的length,又可以访问o的size方法的length,为什么要这样做?写过jquery插件的人可能会比较清楚,我们很多方法都是直接在jquery.fn(jquery的原型对象,也是jquery.prototype属性)上进行扩展的。

 

下面是jquery框架构建jquery的代码。其实上面的思路就是仿造下面的代码实现的。只不过jquery的原型对象我们换成了o而已。

?
01
02
03
04
05
06
07
08
09
10
11
12
var $ = jQuery = function (){
     return new jQuery.fn.init();
}
jQuery.fn = jQuery.prototype = {
     init: function (){
         return this ;
     },
     jquery: "1.2.3" ,
     length:100
}
jQuery.fn.init.prototype = jQuery.fn;
alert($().length);

3. $是粘合剂

其实$就好像一个粘合剂一样,把上面我们分解出来的三个对象粘合起来,不仅保持init的this的作用域的独立,也能让jquery.fn上扩展的对象访问到this,这样进行扩展就非常方便了。

你可能感兴趣的:(“Jquery对象”的本质和构造思路)