Java程序员的JavaScript学习笔记(9—— jQuery工具方法)

计划按如下顺序完成这篇笔记:

1.    理念。

2.    属性复制和继承。

3.    this/call/apply。

4.    闭包/getter/setter。

5.    prototype。

6.    面向对象模拟。

7.    jQuery基本机制。

8.    jQuery选择器。

9.    jQuery工具方法。

10.    jQuery-在“类”层面扩展。

11.    jQuery-在“对象”层面扩展。

12.    jQuery-扩展选择器。

13.    jQuery UI。

14.    扩展jQuery UI。

这是笔记的第9篇,从jQuery源码的角度,聊聊jQuery的工具方法。

1、先看几个工具方法如何使用:

var t = $.trim(‘   >>_<<   ‘);

var ps = $.param({x:15,y:16});

jQuery.type(function(){}) === "function"

jQuery的工具方法,相对jQuery本身,是相对独立的。

2、这些方法是如何定义的呢?

我们猜测一下,试试看。

我们知道jQuery(即$)是全局变量,这些方法应该是jQuery变量的属性。

我们可以通过如下语法添加:

jQuery.xx = function(a,b){

return a + b;

}

// try

var r1 = jQuery.xx(2,3);

console.log(r1);// output : 5

var r2 = $.xx(3,3);

console.log(r2);// output : 6

上面代码,说明$和jQuery引用了相同变量,他们是一样一样的。

这些代码达到了定义工具方法的目的,但jQuery是这样做的吗?

3、

查看jQuery源代码,jQuery通过如下语法定义工具方法:

jQuery.extend({

noConflict: function( deep ) {

if ( window.$ === jQuery ) {

window.$ = _$;

}

if ( deep && window.jQuery === jQuery ) {

window.jQuery = _jQuery;

}

return jQuery;

}

//, ...

});

extend方法定义如下:

//定义了一个方法,赋值给jQuery.fn.extend和jQuery.extend.

//jQuery.fn.extend和jQuery.extend虽然定义相同,但调用者不同,从而方法中this指向不同,从而实现的功能不同。

//没有显式声明参数,而是通过arguments动态获得,从而支持更丰富的功能。

jQuery.extend = jQuery.fn.extend = function() {

var src, copyIsArray, copy, name, options, clone,

// 将第一个参数作为目标对象

target = arguments[0] || {},

// i初始化为1,暂时还不知道做什么用

i = 1,

// length表示参数的个数

length = arguments.length,

// deep 应该表示是否深层拷贝,默认为否。

deep = false;

// Handle a deep copy situation

if ( typeof target === "boolean" ) {

//如果第一个参数是布尔类型,则第二个参数为目标对象

//形如:jQuery.extend(false,UiObject,...);

deep = target;

target = arguments[1] || {};

// skip the boolean and the target

// i 是当前参数的数组下标,从0开始

i = 2;

}

// Handle case when target is a string or something (possible in deep copy)

//目标对象是能是函数或者对象,传入其他参数,target默认为空对象。

if ( typeof target !== "object" && !jQuery.isFunction(target) ) {

target = {};

}

// extend jQuery itself if only one argument is passed

// 目前,如果第一个参数不是布尔,i值为1,length也为1,即extend(obj)的情况

// 如果是布尔,i值为2,length也为2,即extend(true,obj)的情况

// 总之,没有传入 src

if ( length === i ) {

// jQuery 把传入参数收了

// 参数下标重新指向传入的这个参数,即此时指向了src

target = this;

--i;

}

// 现在i指向了target后面某个参数,应该是src

// 把后面传入的每个参数都当src

for ( ; i < length; i++ ) {

// Only deal with non-null/undefined values

// 这样过滤非空啊,如果是undefined会被过滤掉吗?

// 不做 typeof src 是否 "object"、"function"的判断吗?

if ( (options = arguments[ i ]) != null ) {

// 赋值给变量 options

// Extend the base object

for ( name in options ) {

src = target[ name ];

copy = options[ name ];

// 思虑万全:如果已经是自家人,就别嘚瑟了

// Prevent never-ending loop

if ( target === copy ) {

continue;

}

// Recurse if we‘re merging plain objects or arrays

// 对普通对象和数组,考虑递归深层拷贝

// 问题来了,什么叫普通对象? function 算不算?

if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {

if ( copyIsArray ) {

// 设下次循环的默认值

copyIsArray = false;

// 目标对象如果原来有这个属性,但不是数组类型,就被干掉了

clone = src && jQuery.isArray(src) ? src : [];

} else {

// 目标对象如果原来没有这个属性或者不是普通对象,默认为{}。

// 如果已经有了而且是普通对象,那就用它了

clone = src && jQuery.isPlainObject(src) ? src : {};

}

//递归调

//如果写成 jQuery.extend( deep, clone, copy ) 是否一样

// Never move original objects, clone them

target[ name ] = jQuery.extend( deep, clone, copy );

// Don‘t bring in undefined values

// 对 undefined 和 != null 还要加深理解

} else if ( copy !== undefined ) {

// 临门一脚,如果是 jQuery.extend({xx,xfasf});的情况,扩展的是this,即调用者。

// 对target直接修改,也没创建clone啥的

target[ name ] = copy;

}

}

}

}

// Return the modified object

return target;

};

4、再看看jQuery.isPlainObject如何定义的

isPlainObject: function( obj ) {

// Must be an Object.

// Because of IE, we also have to check the presence of the constructor property.

// Make sure that DOM nodes and window objects don‘t pass through, as well

// 翻译:

// 必须是一个对象。

// 因为IE的缘故,我们还必须检查是否有constructor属性。

// 确认别放过Dom节点和window对象,他们不是普通对象。

if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {

// 以下不通过空、undefined、0、jQuery.type返回不是object的、dom对象、window对象

// 所以 typeof 为string、number、function、正则、date的都不成

return false;

}

try {

// Not own constructor property must be Object

if ( obj.constructor &&

!core_hasOwn.call(obj, "constructor") &&

!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {

return false;

}

} catch ( e ) {

// IE8,9 Will throw exceptions on certain host objects #9897

return false;

}

// 枚举的时候,自有属性会先被枚举出来,如果最后一个属性是自有属性,那么所有属性都是自有属性。

// 简而言之,不能有继承来的,可以被枚举到的属性,你妹!为什么有这样的要求?

// Own properties are enumerated firstly, so to speed up,

// if last one is own, then all properties are own.

var key;

for ( key in obj ) {}

return key === undefined || core_hasOwn.call( obj, key );

}

5、

试试看

jQuery.extend({

sayHi:function(you){

console.log(‘hi‘,you);

}

});

$.sayHi(‘Stanley‘); // output : hi Stanley

还不错!如果想覆盖jQuery已有的方法呢?

jQuery.extend({

isPlainObject:function(obj){

return ‘baby, I am not sure.‘;

}

});

var r = $.isPlainObject({});

console.log(r); // output : baby, I am not sure.

这...好吧,可以得逞。想想别的办法吧,不能这样。

再玩儿:

jQuery.extend({

extend:function(obj){

// do nothing

return ‘who am i?‘;

}

});

var r = $.extend({x:function(){ alert();}});

console.log(r); // output : who am i?

jQuery.x();// error : function not be defined

又得逞,这样,再没人可以通过extend扩展jQuery的方法了。

但有更直接的方法。

时间: 2024-10-07 04:45:53

Java程序员的JavaScript学习笔记(9—— jQuery工具方法)的相关文章

Java程序员的JavaScript学习笔记 (目录)

终于完结了,历时半个月. 内容包括: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源码级解析. jQuery EasyUI源码级解析. Java程序员的JavaScript学习笔记(1——理念) Java程序员的JavaScript学习笔记(2——属性复制和继承) Java程序员的JavaScript学习笔记(3——this/call/apply) Java程序员的JavaScript学习笔记(4——this/闭包/getter/setter) Java

Java程序员的JavaScript学习笔记(14——扩展jQuery UI)

计划按如下顺序完成这篇笔记: Java程序员的JavaScript学习笔记(1--理念) Java程序员的JavaScript学习笔记(2--属性复制和继承) Java程序员的JavaScript学习笔记(3--this/call/apply) Java程序员的JavaScript学习笔记(4--this/闭包/getter/setter) Java程序员的JavaScript学习笔记(5--prototype) Java程序员的JavaScript学习笔记(6--面向对象模拟) Java程序员

Java程序员的JavaScript学习笔记(汇总目录)

终于完结了,历时半个月. 内容包括: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源码级解析. jQuery EasyUI源码级解析. Java程序员的JavaScript学习笔记(1--理念) Java程序员的JavaScript学习笔记(2--属性复制和继承) Java程序员的JavaScript学习笔记(3--this/call/apply) Java程序员的JavaScript学习笔记(4--this/闭包/getter/setter) Java

Java程序员的JavaScript学习笔记(5——prototype和Object内置方法)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. 闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第5篇,聊聊prototype.内置的Object对象和Object对象的属性和

Java程序员的JavaScript学习笔记(2——属性复制和继承)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. this/闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第2篇,聊聊属性复制和继承的事情.非常基础,同样,也非常重要. 一切皆

Java程序员的JavaScript学习笔记(6——面向对象模拟)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. 闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第6篇,对前面5篇做一个总结,聊聊JavaScript在面向大型复杂任务时候,如

Java程序员的JavaScript学习笔记(7——jQuery基本机制)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. 闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第7篇,聊聊jQuery基本机制,学习的同时,我们试图实现一个缩略版本的jQue

Java程序员的JavaScript学习笔记(4——闭包/getter/setter)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. 闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第4篇,聊聊闭包/getter/setter,看看JavaScript中的变量作

Java程序员的JavaScript学习笔记(1——理念)

计划按如下顺序完成这篇笔记: 理念. 关于属性复制. this和闭包. 应该熟悉的语法习惯. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 每一篇也许几句话,也许长篇大论.短的可能是因为概念难理解,需要慢慢消化:长的,可能是因为内容多而且水,但不提又不行. 现在开始第1篇:理念. 众

Java程序员的JavaScript学习笔记(3——this/call/apply)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. 闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第3篇,聊聊JavaScript中的this,还有两种调用函数的特殊方式:cal