首页 > 网站 > WEB开发 > 正文

jQuery静态方法isPlainObject,isEmptyObject方法使用和源码分析

2024-04-27 14:06:35
字体:
来源:转载
供稿:网友

jQuery静态方法isPlainObject,isEmptyObject方法使用和源码分析

isPlainObject方法

测试对象是否是纯粹的对象(通过 "{}" 或者 "new Object" 创建的)

示例:

//测试是否为纯粹的对象jQuery 代码:jQuery.isPlainObject({}) // truejQuery.isPlainObject("test") // false

源码分析:

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     if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {          return false;     }

接受一个待检测的对象,首先列出了几个不满足的条件

1.obj能转换为false

2.不是object类型

3.是dom对象

4.是window对象

如果以上条件任意一条成立返回false

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;}

由于ie会8,9在处理特定宿主对象的时候会报错所以采用了try语句,如果走到这里说明参数obj一定是对象类型,但此时的对象类型有可能是自定义构造函数创建的,所以有必要进行过滤,如果以下条件都满足则表示为自定义构造函数创建的

1.有constructor属性 到现在为止我都没有搞清楚这句话什么意思,无论以哪种方式创建对象都是有constructor属性的如果你看到了这里希望给我一个合理的解释谢谢

2.参数的属性constrctor是非继承属性 正常情况下,这个属性存放于构造函数的原型对象中是继承属性,如果不是说明在构造函数里面手动指定了

3.如果参数的构造函数里面没有非继承属性isPrototypeOf说明是自定义的构造函数创建的,为了更好的理解这一段条件下面做一些代码测试:

 function Person(){};     Person.prototype={     constructor:Person } var obj=new Person(); alert(!!obj.constructor); alert(!obj.hasOwnProperty('constructor')); alert(!obj.constructor.prototype.hasOwnProperty('isPrototypeOf'));

既然是过滤自定义构造函数的那就用用自定义的检测一下,执行结果

truetruetrue

果然是3个都满足,这样会顺利返回false,下面采用new Object方式

var obj=new Object();

运行结果如下

truetruefalse

由于第3个结果为false所以不会返回false似乎也是正确的,下面采用字面量方式创建对象

var obj={};

运行结果跟new关键字创建是一样的看到结果令我很困惑的事情出现了,第一个条件和第二个条件有何用?都是返回ture只有第三个条件在起作用不是吗?参考《技术内幕》书中对第一个判断的解释是:”如果对象obj没有属性constructor,则说明该对象是通过对象字面量{}创建的”,对象字面量创建的对象没有constructor属性?肯定是有的啊,再说了即使可以判断但没有意思啊,字面量对象不在过滤范围内啊,笔者很困惑希望大家给予评论解惑感激不尽。

// 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 || hasOwn.call( obj, key );

for...in循环中先循环的是非继承属性然后是继承属性,当然非继承属性的propertyIsEnumerable必须为true利用这个原理如果最后被循环的属性是继承属性那就返回false,如果最后一个是非继承属性那就肯定全是非继承属性返回true

最后附上完整源码:

    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        if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {            return false;        }        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.        var key;        for ( key in obj ) {}        return key === undefined || hasOwn.call( obj, key );    },

isEmptyObject方法

测试对象是否是空对象(不包含任何属性)。

示例:

//测试是否为空对象jQuery.isEmptyObject({}) // truejQuery.isEmptyObject({ foo: "bar" }) // false

源码分析:

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

只要for循环执行了,说明obj不是空的否则返回true,这种判断很简单没有判断参数是否是对象的情况下就直接循环了,你甚至可以用它来判断是否是空字符串

var str='str';var empty='';alert($.isEmptyObject(str));  //falsealert($.isEmptyObject(empty));  //true


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表