当前位置:编程学习 > JS >>

jQuery源码分析-03构造jQuery对象-工具函数

答案:作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com
声明:本文为原创文章,如需转载,请注明来源并保留原文链接。
读读写写,不对的地方请告诉我,多多交流共同进步,本章的的PDF等本章写完了发布。
jQuery源码分析系列的目录请查看 http://nuysoft.iteye.com/blog/1177451,想系统的好好写写,目前还是从我感兴趣的部分开始,如果大家有对哪个模块感兴趣的,建议优先分析的,可以告诉我,一起学习。
3.4 其他静态工具函数
复制代码 代码如下:

// 扩展工具函数
jQuery.extend({
// 释放$的 jQuery 控制权
// 许多 JavaScript 库使用 $ 作为函数或变量名,jQuery 也一样。
// 在 jQuery 中,$ 仅仅是 jQuery 的别名,因此即使不使用 $ 也能保证所有功能性。
// 假如我们需要使用 jQuery 之外的另一 JavaScript 库,我们可以通过调用 $.noConflict() 向该库返回控制权。
// 通过向该方法传递参数 true,我们可以将 $ 和 jQuery 的控制权都交还给另一JavaScript库。
noConflict: function( deep ) {
// 交出$的控制权
if ( window.$ === jQuery ) {
window.$ = _$;
}
// 交出jQuery的控制权
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
},
// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,
// A counter to track how many items to wait for before
// the ready event fires. See #6781
// 一个计数器,用于跟踪在ready事件出发前的等待次数
readyWait: 1,
// Hold (or release) the ready event
// 继续等待或触发
holdReady: function( hold ) {
if ( hold ) {
jQuery.readyWait++;
} else {
jQuery.ready( true );
}
},
// Handle when the DOM is ready
// 文档加载完毕句柄
ready: function( wait ) {
// Either a released hold or an DOMready/load event and not yet ready
//
if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
// 确保document.body存在
if ( !document.body ) {
return setTimeout( jQuery.ready, 1 );
}
// Remember that the DOM is ready
jQuery.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
// If there are functions bound, to execute
readyList.resolveWith( document, [ jQuery ] );
// Trigger any bound ready events
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger( "ready" ).unbind( "ready" );
}
}
},
// 初始化readyList事件处理函数队列
// 兼容不同浏览对绑定事件的区别
bindReady: function() {
if ( readyList ) {
return;
}
readyList = jQuery._Deferred();
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
return setTimeout( jQuery.ready, 1 );
}
// Mozilla, Opera and webkit nightlies currently support this event
// 兼容事件,通过检测浏览器的功能特性,而非嗅探浏览器
if ( document.addEventListener ) {
// Use the handy event callback
// 使用较快的加载完毕事件
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
// 注册window.onload回调函数
window.addEventListener( "load", jQuery.ready, false );
// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
// 确保在onload之前触发onreadystatechange,可能慢一些但是对iframes更安全
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// A fallback to window.onload, that will always work
// 注册window.onload回调函数
window.attachEvent( "onload", jQuery.ready );
// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;
try {
toplevel = window.frameElement == null;
} catch(e) {}
if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
}
},
// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
// 是否函数
isFunction: function( obj ) {
return jQuery.type(obj) === "function";
},
// 是否数组
// 如果浏览器有内置的 Array.isArray 实现,就使用浏览器自身的实现方式,
// 否则将对象转为String,看是否为"[object Array]"。
isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
},
// A crude way of determining if an object is a window
// 简单的判断(判断setInterval属性)是否window对象
isWindow: function( obj ) {
return obj && typeof obj === "object" && "setInterval" in obj;
},
// 是否是保留字NaN
isNaN: function( obj ) {
// 等于null 或 不是数字 或调用window.isNaN判断
return obj == null || !rdigit.test( obj ) || isNaN( obj );
},
// 获取对象的类型
type: function( obj ) {
// 通过核心API创建一个对象,不需要new关键字
// 普通函数不行
// 调用Object.prototype.toString方法,生成 "[object Xxx]"格式的字符串
// class2type[ "[object " + name + "]" ] = name.toLowerCase();
return obj == null ?
String( obj ) :
class2type[ toString.call(obj) ] || "object";
},
// 检查obj是否是一个纯粹的对象(通过"{}" 或 "new Object"创建的对象)
// console.info( $.isPlainObject( {} ) ); // true
// console.info( $.isPlainObject( '' ) ); // false
// console.info( $.isPlainObject( document.location ) ); // true
// console.info( $.isPlainObject( document ) ); // false
// console.info( $.isPlainObject( new Date() ) ); // false
// console.info( $.isPlainObject( ) ); // false
// isPlainObject分析与重构 http://www.zhaoxi.net/article/25047.htm
// 对jQuery.isPlainObject()的理解 http://www.cnblogs.com/phpmix/articles/1733599.html
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
// 必须是一个对象
// 因为在IE8中会抛出非法指针异常,必须检查constructor属性
// DOM节点和window对象,返回false
// obj不存在 或 非object类型 或 DOM节点 或 widnow对象,直接返回false
// 测试以下三中可能的情况:
// jQuery.type(obj) !== "object" 类型不是object,忽略
// obj.nodeType 认为DOM节点不是纯对象
// jQuery.isWindow( obj ) 认为window不是纯对象
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
// Not own constructor property must be Object
// 测试constructor属性
// 具有构造函数constructor,却不是自身的属性(即通过prototype继承的),
if ( obj.constructor &&
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
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 ) {}
// key === undefined及不存在任何属性,认为是简单的纯对象
// hasOwn.call( obj, key ) 属性key不为空,且属性key的对象自身的(即不是通过prototype继承的)
return key === undefined || hasOwn.call( obj, key );
},
// 是否空对象
isEmptyObject: function( obj ) {
for ( var name in obj ) {
return false;
}
return true;
},
// 抛出一个异常
error: function( msg ) {
throw msg;
},
// 解析JSON
// parseJSON把一个字符串变成JSON对象。
// 我们一般使用的是eval。parseJSON封装了这个操作,但是eval被当作了最后手段。
// 因为最新JavaScript标准中加入了JSON序列化和反序列化的API。
// 如果浏览器支持这个标准,则这两个A

上一个:Javascript中的isNaN函数使用说明
下一个:jQuery结合PHP+MySQL实现二级联动下拉列表[实例]

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,