前段时间在阅读javaScript基于原型的面向对象编程相关资料时,对一直在使用的jQuery产生了点疑问,便对其稍作了点研究。
在javascript编程中,生成对象的方式有两种,
第一种,对象字面量方式:
var foo = {
name : "紅一葉",
age : 18
};
第二种就是通过构造器方式创建对象:
function Foo(){
this.name = "紅一葉";
this.age = 18;
}
var foo = new Foo();
在上式中,foo便是由构造器Foo构造出来的对象(在javascript中,函数都可以作为构造器。于是有个不成文的约定,凡是要作为构造器使用的函数首字母大写)。
回到jQuery中,在jQuery中我们最为常用的对象生成方式$("#id"),很显然这种方式和上面两种都不像,让我们通过代码来看看jQuery到底做了什么封装和转换(以下代码取自于jQuery1.9.1);
window.jQuery = window.$ = jQuery;
jQuery = function( selector, context ) {
return new jQuery.fn.init(
selector, context, rootjQuery );
},
通过上面几行代码我们可以看出,jQuery和$是两个等价的全局变量,$("#id")便是调用了上面定义的函数,等价于jQuery("#id"),这个函数的返回值是new
jQuery.fn.init( selector, context, rootjQuery );
也就是说$("#id")其实是调用了init()构造器构造了一个对象并返回。
咱们再细看一下jQuery.fn.init();这个jquery.fn是个什么东东,已及init构造器到底有什么特殊的地方?来咱再上代码来看看
jQuery.fn = jQuery.prototype = {
init: function( selector, context, rootjQuery ) {
......
},
....
};
jQuery.fn.init.prototype = jQuery.fn;
由jQuery.fn =
jQuery.prototype这句可以看出fn是jQuery原型对象的一个引用,实际上fn也没有其他特别的含义,为防止给我们的思维造成混乱,可以把上面代码中的所有fn用jQuery的原型替代(即把所有的jQuery.fn替换成jQuery.prototype)。
至于init构造器有什么特殊的地方,上面我们看到,jQuery中把init的原型指向了jQuery.fn即指向了jQuery的原型,jQuery.prototype。这样做的好处在于,由init()构造器构造的对象就能够通过原型链访问到jQuery原型上的方法和属性。
对于这几个变量的关系,如果有疑问的话可以参照下面的两张图来帮助理解,第一张是我自己画的,第二张百度上借网友的,表示的都是一个意思,只是画的方式不同而已。