首页 > 代码库 > jQuery源码学习笔记:扩展工具函数
jQuery源码学习笔记:扩展工具函数
// 扩展工具函数 jQuery.extend({ // http://www.w3school.com.cn/jquery/core_noconflict.asp // 释放$的 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 // 文档加载完毕句柄 // http://www.cnblogs.com/fjzhou/archive/2011/05/31/jquery-source-4.html 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 onl oad, // 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.jb51.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。 // 如果浏览器支持这个标准,则这两个API是在JS引擎中用Native Code实现的,效率肯定比eval高很多。 // 目前来看,Chrome和Firefox4都支持这个API。 parseJSON: function( data ) { if ( typeof data !== "string" || !data ) { return null; } // Make sure leading/trailing whitespace is removed (IE can't handle it) data = http://www.mamicode.com/jQuery.trim( data );>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。