文章目录
  1. 1. jQuery对象简介
  2. 2. jQuery两种添加插件方式
    1. 2.1. $.extend方式添加插件
    2. 2.2. $.fn.extend方式添加插件
    3. 2.3. 自定义插件标准

jQuery对象简介

在源码中看到jQuery对象其实就是第一个函数表达式,这个函数里面什么都没有干,直接返回了一个init实例化的对象,由于init的原型对象引用指向的就是jQuery,所以这个对象实际就是jQuery的实例。

jQuery = function( selector, context ) {
    //创建jQuery实例
    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    return new jQuery.fn.init( selector, context );
},

...
//jQuery的原型引用传递给jQuery.fn
jQuery.fn = jQuery.prototype
...
// Give the init function the jQuery prototype for later instantiation
//将jQuery原型引用传递给init
init.prototype = jQuery.fn;

经过两次引用传递,init对象就具有jQuery对象的功能了,各个原型之间的关系参考下图:

JavaScript的原型分析可以参考前面的《理解JavaScript原型模式》
将jquery.js引入文档之后,执行jQuery匿名函数的时候传递了window对象,把jQuery与$变量赋值给window,所以这两者通用的,都表示jQuery的实例化对象。我们代码里面就可以用jQuery.ajax(),jQuery.each()等原型中的方法了。

jQuery两种添加插件方式

jQuery里面有两种扩展可以实现自己的插件,一种是$.extend,另一种就是$.fn.extend,源代码里面它们其实指向同一个函数:

jQuery.extend = jQuery.fn.extend = function() {
    var src, copyIsArray, copy, name, options, clone,
    target = arguments[0] || {},//返回的目标对象
    i = 1,
    length = arguments.length,
    deep = false;
    ......
}

从前面的分析大概就明白这两者的区别了,$.extend表示第一次加载进来的实例就添加一个extend函数,而$.fn.extend表示jQuery原型对象上面添加一个extend函数,所以在$.extend里面添加扩展函数可以直接用$.函数名()直接使用,而$.fn.extend需要执行$(选择器).函数名()实例化之后才可以调用扩展函数。可以简单的理解为,$.extend为jQuery全局对象添加方法,$.fn.extend为jQuery实例化添加方法。

$.extend方式添加插件

如果只添加一个参数相当于直接在jquery对象增加了一个属性,如果是多个参数,那么会合并到第一个参数,如:

1、直接添加对象属性为函数

1
2
3
4
5
6
7
var t1 = $.extend({
hello: function() {
console.log('t1 is executed');
}
});
//在全局变量中添加了hello函数
console.log($.hello());

这种方式就直接在jQuery全局对象上添加的函数。

2、另外一种就是拷贝对象

深拷贝,只要对象里面还有对象,会递归的去复制到目标对象,并把以前的值覆盖掉

1
2
3
4
5
6
var child = {name: 'small', age: 1};
var target = {foo: 'duke', child: child};
var opChild = {name:'sm', age:2};
var option = {foo: 'op', child:opChild};
var result = $.extend(target, {foo: 'success'}, option)
console.log(result);

输出结果,:

1
2
//child的属性值全部被覆盖
{name: "sm", age: 2}

浅拷贝对象里面不嵌套的拷贝,如:

1
2
var t3 = $.extend({'realname':'hello', 'password': 111111}, {'password':'222222'});
console.log(t3);

输入结果

1
Object {realname: "hello", password: "222222"}

这种参数扩展非常有用,在jquery插件中常常会用到默认有哪些参数值,然后用户调用的时候可以重写这些参数值,也可以增加额外的参数。

$.fn.extend方式添加插件

前面已经介绍了,$.fn.extend与$.extend指向的是同一个函数,所以两者的功能是一样的,$.fn.extend只是针对原型对象的。写一个简单的扩展就明白了:

1
2
3
4
5
6
7
$.fn.extend({
foo : function() {
console.log('foo');
}
});
console.log($.foo)//输出undefined
$().foo();//输出foo

如果想支持链式调用,可以在自定义的函数里面return一个jquery原型对象就可以了。如下所示:

1
2
3
4
5
6
$.fn.extend({
foo : function() {
return this;//this代表jQuery.prototype原型对象
}
});
$(document).foo().empty();

由于extend函数里面就是把传入的属性赋值给当前对象(jQuery实例或者jQuery原型对象),所以如果只是一个函数扩展的话,也可以直接这样定义:

1
2
3
4
$.fn.foo = function() {
return this;//this代表jQuery.prototype原型对象
};
$(document).foo().empty();

自定义插件标准

上面两种插件方式都是以直接传入参数形式进行扩展的,既然是扩展就应该遵守开闭原则,只对外就行修改,并且不能与原对象造成影响。所以自定义插件应该封装成一个类与外界保持独立,JavaScript虽然没有类但是有命名空间,可以为插件定义一个私有化空间,目前一般都采用匿名函数来定义,如:

1
2
3
4
5
6
7
(function($){
$.fn.foo = function() {
console.log('foo');
return this;
}
})(jQuery);
$(document).foo();//输出foo

可以看到匿名函数传入了jQuery对象,内部函数就可以共享jQuery的很多功能了,所以一般引入其他插件,有一个前提就是必须先引用jquery.js再引用插件的js文件。

文章目录
  1. 1. jQuery对象简介
  2. 2. jQuery两种添加插件方式
    1. 2.1. $.extend方式添加插件
    2. 2.2. $.fn.extend方式添加插件
    3. 2.3. 自定义插件标准