一直做梦的猫

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

jQuery源码分析-03构造jQuery对象-工具函数这篇文章对jQuery中扩展的一些工具函数做了下简要分析

关于isPlainObject函数,isPlainObject分析与重构这篇文章指出其存在bug,history,location,navigator,screen可以顺序通过 isPlainObject的检测返回true.

经本人测试,在ie8中确实存在bug返回true,但chrome中则返回的是false。

经过仔细分析发现bug原因,若obj = window.location, 在ie8中第二个if语句的第一个判断条件obj.constructor的值为undefined,而在chrome中为function Location() { [native code] }

其实第一个if语句的第二个判断条件可以过滤掉window.location等对象jQuery.type()源码为:

type: function( obj ) {
                return obj == null ?
                    String( obj ) :
                    class2type[ toString.call(obj) ] || "object";
            },

class2type是在前面定义的一个空对象:

// [[Class]] -> type pairs
            class2type = {};

因为class2type没有内容,因此通过class2type无法区别window.location与其他object,所以只要obj不为空,都返回“object”。

如果class2type = {"[object Location]": "location",........};则可过滤出location之类的对象

 

isPlainObject完整代码如下

function isPlainObject( 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
    //首先排除掉obj为空、非object类型和window及节点类型
    if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
        return false;
    }

    //前两个判断条件不用多说,第三个判断条件是在obj的原型中找isPrototypeOf这个方法,
    //而这个方法只会存在于Object的原型中,也就是说如果obj的原型中存在isPrototypeOf则obj
    //是Object的直接实例。当然除非人为的将obj的构造函数的prototype.constructor置为Object,
    //或者将构造函数的prototype置为{}
    try {
        // Not own constructor property must be Object
        if ( obj.constructor &&
            !hasOwn.call(obj, "constructor") &&
            !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.
    //因为in操作符只能访问到可枚举类型,若obj原型中有可枚举类型属性则return false
    //保证了obj是Object.prototype未被修改过的Object的直接实例。
    var key;
    for ( key in obj ) {}

    return key === undefined || hasOwn.call( obj, key );
}

 

posted on 2013-05-15 15:32  一直做梦的猫  阅读(225)  评论(0)    收藏  举报