jQuery源码分析6-扩展工具方法1

2017年08月06日Web前端

从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。