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

isPlainObject方法

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

示例:

//测试是否为纯粹的对象
jQuery 代码:
jQuery.isPlainObject({}) // true
jQuery.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‘));

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

true

true

true

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

var obj=new Object();

运行结果如下

true

true

false

由于第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({}) // true
jQuery.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));  //false
alert($.isEmptyObject(empty));  //true
时间: 2024-11-10 11:19:18

jQuery静态方法isPlainObject,isEmptyObject方法使用和源码分析的相关文章

jQuery静态方法inArray,grep,merge,makeArray方法使用和源码分析

inArray方法 确定第一个参数在数组中的位置,从0开始计数(如果没有找到则返回 -1 ). 示例: var arr = [ 4, "Pete", 8, "John" ]; jQuery.inArray("John", arr); //3 jQuery.inArray(4, arr); //0 jQuery.inArray("David", arr); //-1 jQuery.inArray("Pete"

jQuery静态方法parseJSON方法使用和源码分析

该方法接受一个JSON字符串,返回解析后的对象. 传入一个畸形的JSON字符串会抛出一个异常.比如下面的都是畸形的JSON字符串: {test: 1} ( test 没有包围双引号) {'test': 1} (使用了单引号而不是双引号) 另外,如果你什么都不传入,或者一个空字符串.null或undefined,parseJSON都会返回 null . 源码分析: parseJSON: function( data ) { if ( typeof data !== "string" ||

RxJava1.0 flatMap方法的源码分析

RxJava1.0 flatMap方法的源码分析 package com.yue.test; import java.awt.Cursor; import java.util.ArrayList; import java.util.List; import com.yue.bean.Course; import com.yue.bean.Student; import rx.Observable; import rx.Subscription; import rx.Observable.OnSu

Android Debuggerd 简要介绍和源码分析(转载)

转载: http://dylangao.com/2014/05/16/android-debuggerd-%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D%E5%92%8C%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/ 码字很辛苦,转载请注明来自Dylan‘s Zone的<Android Debuggerd 简要介绍和源码分析> 本文以android4.1为基础,分析debuggerd这个工具的使用方法和源码. 1.Debuggerd 简介

java集合框架10——TreeMap和源码分析(一)

前面讨论完了HashMap和HashTable的源码,这一节我们来讨论一下TreeMap.先从整体上把握TreeMap,然后分析其源码,深入剖析TreeMap的实现. 1. TreeMap简介 TreeMap是一个有序的key-value集合,它内部是通过红-黑树实现的,如果对红-黑树不太了解,请先参考下这篇博文:红-黑树.下面我们先来看看TreeMap的继承关系: java.lang.Object ? java.util.AbstractMap<K, V> ? java.util.TreeM

转:《Linux设备驱动程序3》源码目录结构和源码分析经典链接

转自:http://blog.csdn.net/geng823/article/details/37567557 [原创][专栏]<Linux设备驱动程序>--- LDD3源码目录结构和源码分析经典链接 [专栏]Linux设备驱动程序学习(总目录) [专栏]LDD3源码分析链接(总目录) 1. LDD3源码分析之hello.c与Makefile模板 2. LDD3源码分析之字符设备驱动程序 其他错误: 我的Linux内核为 3.2.0-65-generic-pae,在scull目录下make时

jQuery静态方法noConflict的使用和源码分析

所谓静态方法是jQuery本身得公共方法,并不需要通过实例化来调用,一般也称为工具方法,下面先来列绝下jQuery.noConflict方法的用法: noConflict() 方法让渡变量 $ 的 jQuery 控制权. 该方法释放 jQuery 对 $ 变量的控制. 该方法也可用于为 jQuery 变量规定新的自定义名称. var jq=$.noConflict(); 下面来做个测试: <script src='jquery-1.7.1.js'></script> <scr

jQuery静态方法globalEval使用和源码分析

Eval函数大家都很熟悉,但是globalEval方法却很少使用,大多数参考手册也没有相关api,下面就对其用法和源码相应介绍: jQuery.globalEval()函数用于全局性地执行一段JavaScript代码. 示例: var name = "全局变量"; function test(){ var name = "局部变量"; alert(name); // 局部变量 eval( "alert(name);" ); // 局部变量 $.g

jQuery静态方法noop,camelCase,nodeName,trim使用和源码分析

noop方法 jQuery.noop()函数是一个空函数,它什么也不做. 当某些时候你需要传入函数参数,而且希望它什么也不做的时候,你可以使用该函数,也无需再新建一个空的函数. 示例: // 传入一个空函数作为参数,返回一个空数组 // 空函数的返回值为undefined,而null或undefined值会被$.map()忽略掉. var result = $.map( [1, 2, 3], $.noop ); document.writeln( result.length ); // 0 源码