jquery 源码分析四(上)

这次分析的函数就是用extend添加到jQuery下的,这次分析将拆分成片段来讲,首先是最前面几个简单的变量和函数:

//保证当前页面上的每个jQuery都是独一无二的
expando: "jQuery" + ( version + Math.random() ).replace( /D/g, "" ),

isReady: true,
//错误抛出函数
error: function( msg ) {
    throw new Error( msg );
},

noop: function() {},

接下来几个函数会涉及到jQuery的type函数和support中的ownLast,所以先讲解这两个的用处和原理(type就是在这段extend,只是提前分析了):

type: function( obj ) {
    if ( obj == null ) {
        return obj + "";
    }
        //判断obj的类型,若是object或是function,则需要toString进行进一步检查,class2type = {};toString = class2type.toString;
       //class2type中保存了特定类型检测出的键值对
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[ toString.call(obj) ] || "object" :
        typeof obj;
}
var i;
for ( i in jQuery( support ) ) {
    break;
}
support.ownLast = i !== "0";

上面的一段程序就是为了生成ownLast的,support中保存了一些浏览器的怪异行为,ownLast就是其中之一。我们知道正常的for..in..循环,首先是从一个对象的实例属性开始的,然后再循环prototype中的属性。但是在IE9之前的版本中,这个刚好是反过来的。所以在这里,jQuery(support)返回的对象中,第一个i应该是0,但是在IE中的是'andSelf',这是jQuery中prototype里的最后一个属性,所以最后用i与0比较,确定for..in..顺序。

接下来就是对那些函数的分析了:

//根据上面讲的type函数判断传入参数的具体类型
isFunction: function( obj ) {
    return jQuery.type(obj) === "function";
},

isArray: Array.isArray || function( obj ) {
    return jQuery.type(obj) === "array";
},

//window.window == window
isWindow: function( obj ) {
    return obj != null && obj == obj.window;
},

isNumeric: function( obj ) {
    // parseFloat在对普通情况下非数字的判断很准确
    // 但是当数字以进制的字母开头时,判断不准确,特别是十六进制时
    // 同时infinite时,parseFloat返回NaN
    return obj - parseFloat( obj ) >= 0;
},

isEmptyObject: function( obj ) {
    var name;
    for ( name in obj ) {
        return false;
    }
    return true;
},

isPlainObject: function( obj ) {
    var key;

    //首先必须是一个对象
    // 然后我们不能让nodeList等DOM通过这个检验
    if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
        return false;
    }

    try {
        // 没有constructor的对象肯定是个普通的对象
                // 确定constructor可以再当前属性中,但是不应该有prototype中出现
                // 确切来说就是可以有constructor,constructor指向的对象中可以有prototype属性
                //但是其下面不能有isPrototypeOf
        if ( obj.constructor &&
            !hasOwn.call(obj, "constructor") &&
            !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
            return false;
        }
    } catch ( e ) {
        // IE8,9 下会对特定的对象判断产生错误
        return false;
    }

    // 支持IE<9的情况
    // 就是处理那些首先循环继承来的属性而不是自身属性
    if ( support.ownLast ) {
        for ( key in obj ) {
            return hasOwn.call( obj, key );
        }
    }

    // 对于正常情况,首先循环的是自身属性
    // 如果最后一个属性还会自身属性的话,那么所有的属性都是自身属性
    for ( key in obj ) {}

    return key === undefined || hasOwn.call( obj, key );
}
globalEval: function( data ) {
    if ( data && jQuery.trim( data ) ) {
        // 在IE中使用 execScript 
        // 我们通过call的方法,使得上下文环境变为window,与execScript统一
        ( window.execScript || function( data ) {
            window[ "eval" ].call( window, data );
        } )( data );
    }
},

// 主要使用在css中
// 处理MicroSoft忘记在属性前加供应商名称
camelCase: function( string ) {
    return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
},
//判断传入的element的nodeName和name是否相同
nodeName: function( elem, name ) {
    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
},

先写这一部分,晚点再对后半部分写一篇上来,最近坑爹的天气,搞得直接就感冒了,头昏昏沉沉的。。。

原文地址:https://www.cnblogs.com/cyITtech/p/3586591.html