jQuery源码分析6-扩展工具方法1
从355-840,用extend扩展了一系列的jQ工具方法。本次先看前几个方法和属性。
一、noConflict()
在一个项目中,我们往往不止使用一个库或者框架,那么对$的使用就会出现冲突(比如mootools)。此时就需要使用到noConflict这个避免冲突的方法。
noConflict: function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
}
当我们先引入一个使用$的库,在引入jQuery,像这样:
<script type="text/javascript" src="mootools.js"></script>
<script type="text/javascript" src="jquery-1.8.3.js"></script>
此时我们调用noConflict方法。此时window.$与jQuery是相等。会给window下的$重新赋值。而_$在一开始是有定义的,
_$ = window.$,
_jQuery = window.jQuery,
在jQuery一开始运行时,就提前保留了window下的$和jQuery属性,尽管他们会在jQuery运行后被覆盖。 所以运行后,$又变回了加载jQuery库前的那个对象了。如果传了true参数,他也会将jQuery的控制权限给释放掉。 函数的最后return了jQuery对象自己,是为了让开发者可以重新命名jQuery对象。
var jq = $.noConflict();
jq('#box');
二、isReady
该属性表示DOM是否ready,在ready方法中有用处。
三、readyWait
数值,用于holdReady中计数。
四、holdReady()
该方法可以暂停或者恢复jQuery.ready()事件。 在后面的DOM加载中详细说明。
五、ready()
同holdReady方法,在后面的DOM加载中详细说明。
六、isFunction()
用于判断参数是否是function类型,利用的是type工具方法。实现如下:
return jQuery.type(obj) === "function";
七、isArray()
用于判断参数是否是array类型,也是使用的type方法。
八、isWindow()
判断参数是否是window对象。实现如下:
return obj != null && obj == obj.window;
以后在没有使用jQuery库的地方,可以尝试使用这个方法。
九、isNumeric()
判断参数是否是数字或者是数值型字符串。实现是:
return !isNaN( parseFloat(obj) ) && isFinite( obj );
这个参数的parseFloat形式必须是非NaN,且该值能转成有限的数字。
十、type()
用于判断参数的类型,与js自带的typeof不同,该方式可以具体到变量的类型。而不是子返回个object。
class2type = {}; // 93行
core_toString = Object.prototype.toString; // 37行
// 900行
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
type: function( obj ) {
return obj == null ?
String( obj ) :
class2type[ core_toString.call(obj) ] || "object";
}
jQ利用了object对象原型上的toSting方法,再利用call方法。每个变量都会输出[object 类型]这种格式,此时,我们只需要去class2type对象中按键匹配就行了。 这种判断方式不错,可以特别记忆下。
十一、isPlainObject()
判断参数是否是一个通过字面量形式{}或new Object创建的对象。
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
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 );
....
// 38行
core_hasOwn = Object.prototype.hasOwnProperty,
首先第一个if过滤掉undefined、false、空字符串以及type类型不是object的,Dom节点,和window对象
接着使用try..catch..防止ie8、9下的报错。当参数还有constructot,该属性是他本身就有的,且constructor的原型上自带了isPrototypeOf这属性时,将正常通过try中的if。
十二、isEmptyObject()
该方法用于判断参数是否是空对象。
var name;
for ( name in obj ) {
return false;
}
return true;
利用for..in..遍历该参数是否有属性,若有则是含有属性,为非空对象,反之亦然。
十三、error()
用于控制台的error输出。
throw new Error( msg );
十四、parseHTML()
该方法用来解析html字符串。
parseHTML: function( data, context, scripts ) { // scripts是否解析script标签
var parsed;
if ( !data || typeof data !== "string" ) {
return null;
}
if ( typeof context === "boolean" ) { // 对两个参数(无context)时进行特殊处理
scripts = context;
context = 0;
}
context = context || document;
// Single tag
if ( (parsed = rsingleTag.exec( data )) ) { // 单标签,创建他,所以text加不上。
return [ context.createElement( parsed[1] ) ];
}
parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] );
return jQuery.merge( [],
(parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes );
}
第一个参数是html字符串。第二个参数是上下文环境,不赋值的话,就是默认的document。第三个参数是个布尔值,表示是否解析script标签。 第一个if过滤null、undefined、空字符串以及非字符串类型的值。
第二个if处理两个参数时的情况,将第二个参数的布尔值赋值给scripts。
context值取外部传入的或者是默认的document。第三个if,判断是否是单标签,当是单标签时,直接使用createElement方法创建他,返回的是数组形式的。
如果是多标签的话,会调用buildFragment()这个方法去创建这个方法等遇到时在解释。最后调用merge并return。