首页 文章

对象是空的吗? [重复]

提问于
浏览
454

这个问题在这里已有答案:

检查对象是否为空的最快方法是什么?

有没有比这更快更好的方法:

function count_obj(obj){
    var i = 0;
    for(var key in obj){
        ++i;
    }

    return i;
}

24 回答

  • 55
    function isEmpty( o ) {
        for ( var p in o ) { 
            if ( o.hasOwnProperty( p ) ) { return false; }
        }
        return true;
    }
    
  • 1

    我假设你的意思是"has no properties of its own" .

    // Speed up calls to hasOwnProperty
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    
    function isEmpty(obj) {
    
        // null and undefined are "empty"
        if (obj == null) return true;
    
        // Assume if it has a length property with a non-zero value
        // that that property is correct.
        if (obj.length > 0)    return false;
        if (obj.length === 0)  return true;
    
        // If it isn't an object at this point
        // it is empty, but it can't be anything *but* empty
        // Is it empty?  Depends on your application.
        if (typeof obj !== "object") return true;
    
        // Otherwise, does it have any properties of its own?
        // Note that this doesn't handle
        // toString and valueOf enumeration bugs in IE < 9
        for (var key in obj) {
            if (hasOwnProperty.call(obj, key)) return false;
        }
    
        return true;
    }
    

    例子:

    isEmpty(""), // true
    isEmpty(33), // true (arguably could be a TypeError)
    isEmpty([]), // true
    isEmpty({}), // true
    isEmpty({length: 0, custom_property: []}), // true
    
    isEmpty("Hello"), // false
    isEmpty([1,2,3]), // false
    isEmpty({test: 1}), // false
    isEmpty({length: 3, custom_property: [1,2,3]}) // false
    

    如果您只需要处理ECMAScript5 browsers,则可以使用Object.getOwnPropertyNames而不是hasOwnProperty循环:

    if (Object.getOwnPropertyNames(obj).length > 0) return false;
    

    这将确保即使对象仅具有非可枚举属性, isEmpty 仍将为您提供正确的结果 .

  • 427

    对于ECMAScript5(尽管在所有浏览器中都不支持),您可以使用:

    Object.keys(obj).length === 0
    
  • 1

    EDIT :请注意,您应该使用ES5 solution代替此,因为ES5支持目前是widespread . 它仍适用于jQuery .


    简单和跨浏览器的方式是使用 jQuery.isEmptyObject

    if ($.isEmptyObject(obj))
    {
        // do something
    }
    

    更多:http://api.jquery.com/jQuery.isEmptyObject/

    你需要jquery .

  • 12

    如果您不介意添加额外的库,Underscorelodash每个都有一个方便的 isEmpty() 功能 .

    _.isEmpty({});
    
  • -1

    让这个宝宝上床睡觉;在Node,Chrome,Firefox和IE 9下测试,很明显,对于大多数用例:

    • (for...in...) is the fastest option to use!

    • Object.keys(obj).length is 10 times slower for empty objects

    • JSON.stringify(obj).length is always the slowest (不奇怪)

    • Object.getOwnPropertyNames(obj).length takes longer than Object.keys(obj).length 在某些系统上可能会长得多 .

    明智的底线表现,使用:

    function isEmpty(obj) { 
       for (var x in obj) { return false; }
       return true;
    }
    

    要么

    function isEmpty(obj) {
       for (var x in obj) { if (obj.hasOwnProperty(x))  return false; }
       return true;
    }
    

    节点下的结果:

    • 第一个结果: return (Object.keys(obj).length === 0)

    • 第二个结果: for (var x in obj) { return false; }...

    • 第三个结果: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...

    • 结果: return ('{}' === JSON.stringify(obj))

    使用0键测试对象0.00018 0.000015 0.000015 0.000324

    使用1个键测试对象0.000346 0.000458 0.000577 0.000657

    使用2个键0.000375 0.00046 0.000565 0.000773测试对象

    使用3个键测试对象0.000406 0.000476 0.000577 0.000904

    使用4个键测试对象0.000435 0.000487 0.000589 0.001031

    使用5个键测试对象0.000465 0.000501 0.000604 0.001148

    使用6个键测试对象0.000492 0.000511 0.000618 0.001269

    用7个键测试对象0.000528 0.000527 0.000637 0.00138

    用8个键测试对象0.000565 0.000538 0.000647 0.00159

    使用100个键测试对象0.003718 0.00243 0.002535 0.01381

    使用1000个键测试对象0.0337 0.0193 0.0194 0.1337

    请注意,如果您的典型用例使用少量键测试非空对象,并且很少使用10个或更多键测试空对象或对象,请考虑Object.keys(obj).length选项 . - 否则请使用更通用的(for ... in ...)实现 .

    请注意,Firefox似乎更快地支持Object.keys(obj).length和Object.getOwnPropertyNames(obj).length,使其成为任何非空对象的更好选择,但是当涉及到空对象时,( for ... in ...)只是快了10倍 .

    我的2美分是Object.keys(obj).length是一个糟糕的主意,因为它创建一个键对象来计算内部有多少键,而不是销毁它!为了创建该对象,他需要循环键...所以为什么要使用它而不是(for ... in ...)选项:)

    var a = {};
    
    function timeit(func,count) {
       if (!count) count = 100000;
       var start = Date.now();
       for (i=0;i<count;i++) func();
       var end = Date.now();
       var duration = end - start;
       console.log(duration/count)
    }
    
    function isEmpty1() {
        return (Object.keys(a).length === 0)
    }
    function isEmpty2() {
        for (x in a) { return false; }
        return true;
    }
    function isEmpty3() {
        for (x in a) { if (a.hasOwnProperty(x))  return false; }
        return true;
    }
    function isEmpty4() {
        return ('{}' === JSON.stringify(a))
    }
    
    
    for (var j=0;j<10;j++) {
       a = {}
       for (var i=0;i<j;i++) a[i] = i;
       console.log('Testing for Object with '+Object.keys(a).length+' keys')
       timeit(isEmpty1);
       timeit(isEmpty2);
       timeit(isEmpty3);
       timeit(isEmpty4);
    }
    
    a = {}
    for (var i=0;i<100;i++) a[i] = i;
    console.log('Testing for Object with '+Object.keys(a).length+' keys')
    timeit(isEmpty1);
    timeit(isEmpty2);
    timeit(isEmpty3);
    timeit(isEmpty4, 10000);
    
    a = {}
    for (var i=0;i<1000;i++) a[i] = i;
    console.log('Testing for Object with '+Object.keys(a).length+' keys')
    timeit(isEmpty1,10000);
    timeit(isEmpty2,10000);
    timeit(isEmpty3,10000);
    timeit(isEmpty4,10000);
    
  • 4

    优雅的方式 - 使用键

    var myEmptyObj = {};
    var myFullObj = {"key":"value"};
    console.log(Object.keys(myEmptyObj).length); //0
    console.log(Object.keys(myFullObj).length); //1
    

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

  • 0

    很惊讶在这样一个基本的JS问题上看到这么多弱的答案......由于这些原因,最佳答案也不好:

    • 它生成一个全局变量

    • undefined 上返回 true

    • 使用 for...in ,这本身就非常慢
      for...in 里面

    • 函数没用 - 返回 false 没有 hasOwnProperty 魔法会工作正常

    事实上,有一个更简单的解决方案:

    function isEmpty(value){
        return Boolean(value && typeof value == 'object') && !Object.keys(value).length;
    });
    
  • 0
    var x= {}
    var y= {x:'hi'}
    console.log(Object.keys(x).length===0)
    console.log(Object.keys(y).length===0)
    
    true
    false
    

    http://jsfiddle.net/j7ona6hz/1/

  • 543

    https://lodash.com/docs#isEmpty非常方便:

    _.isEmpty({})   // true
    _.isEmpty()     // true
    _.isEmpty(null) // true
    _.isEmpty("")   // true
    
  • 6

    这有多糟糕?

    function(obj){
        for(var key in obj){
            return false; // not empty
        }
    
        return true; // empty
    }
    
  • 22

    不需要图书馆 .

    function(){ //must be within a function
     var obj = {}; //the object to test
    
     for(var isNotEmpty in obj) //will loop through once if there is a property of some sort, then
        return alert('not empty')//what ever you are trying to do once
    
     return alert('empty'); //nope obj was empty do this instead;
    }
    
  • 96

    这可能有点hacky . 你可以试试这个 .

    if (JSON.stringify(data).length === 2) {
       // Do something
    }
    

    不确定这个方法是否有 disadvantage .

  • -1

    快速在线搜索'词典'对象:

    function isEmptyDict(d){for (var k in d) return false; return true}
    
  • 29

    如果Array.isArray和Object.getOwnPropertyNames不可用,您可以编写回退

    XX.isEmpty = function(a){
        if(Array.isArray(a)){
            return (a.length==0);
        }
        if(!a){
            return true;
        }
        if(a instanceof Object){
    
            if(a instanceof Date){
                return false;
            }
    
            if(Object.getOwnPropertyNames(a).length == 0){
                return true;
            }
        }
        return false;
    }
    
  • 15

    想象一下,你有以下对象:

    var obj1= {};
    var obj2= {test: "test"};
    

    不要忘记我们不能使用===符号来测试对象相等性,因为它们可以继承,所以如果你使用ECMA 5和javascript的高级版本,答案很简单,你可以使用下面的函数:

    function isEmpty(obj) {
       //check if it's an Obj first
       var isObj = obj !== null 
       && typeof obj === 'object' 
       && Object.prototype.toString.call(obj) === '[object Object]';
    
       if (isObj) {
           for (var o in obj) {
               if (obj.hasOwnProperty(o)) {
                   return false;
                   break;
               }
           }
           return true;
       } else {
           console.error("isEmpty function only accept an Object");
       }
    }
    

    所以结果如下:

    isEmpty(obj1); //this returns true
    isEmpty(obj2); //this returns false
    isEmpty([]); // log in console: isEmpty function only accept an Object
    
  • 1
    funtion isEmpty(o,i)
    {
        for(i in o)
        {
            return!1
        }
        return!0
    }
    
  • 0

    这是一个很好的方法

    function isEmpty(obj) {
      if (Array.isArray(obj)) {
        return obj.length === 0;
      } else if (typeof obj === 'object') {
        for (var i in obj) {
          return false;
        }
        return true;
      } else {
        return !obj;
      }
    }
    
  • -1
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    function isArray(a) {
        return Object.prototype.toString.call(a) === '[object Array]'
    }
    function isObject(a) {
        return Object.prototype.toString.call(a) === '[object Object]'
    }
    function isEmpty(a) {
        if (null == a || "" == a)return!0;
        if ("number" == typeof a || "string" == typeof a)return!1;
        var b = !0;
        if (isArray(a)) {
            if (!a.length)return!0;
            for (var c = 0; c < a.length; c++)isEmpty(a[c]) || (b = !1);
            return b
        }
        if (isObject(a)) {
            for (var d in a)hasOwnProperty.call(a, d) && (isEmpty(a[d]) || (b = !1));
            return b
        }
        return!0
    }
    
  • 217

    也许你可以使用这个决定:

    var isEmpty = function(obj) {
      for (var key in obj)
        if(obj.hasOwnProperty(key))
          return false;
      return true;
    }
    
  • 13

    我修改了Sean Vieira的代码以满足我的需求 . null和undefined根本不算作对象,数字,布尔值和空字符串返回false .

    'use strict';
    
    // Speed up calls to hasOwnProperty
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    
    var isObjectEmpty = function(obj) {
        // null and undefined are not empty
        if (obj == null) return false;
        if(obj === false) return false;
        if(obj === true) return false;
        if(obj === "") return false;
    
        if(typeof obj === "number") {
            return false;
        }   
        
        // Assume if it has a length property with a non-zero value
        // that that property is correct.
        if (obj.length > 0)    return false;
        if (obj.length === 0)  return true;
    
        // Otherwise, does it have any properties of its own?
        // Note that this doesn't handle
        // toString and valueOf enumeration bugs in IE < 9
        for (var key in obj) {
            if (hasOwnProperty.call(obj, key)) return false;
        }
        
        
        
        return true;
    };
    
    exports.isObjectEmpty = isObjectEmpty;
    
  • 0
    if (Object.getOwnPropertyNames(obj1).length > 0)
    {
     alert('obj1 is empty!');
    }
    
  • 3

    我的解决方案

    function isEmpty(value) {
        if(Object.prototype.toString.call(value) === '[object Array]') {
            return value.length == 0;
        } else if(value != null && typeof value === 'object') {
            return Object.getOwnPropertyNames(value).length  == 0;
        } else {
            return !(value || (value === 0));
        }
    }
    

    CHEARS

  • 1

    一个对象是一个关联数组,用原型扩充 . Object.is()方法确定两个值是否相同 .

    对象比较: -

    Object.is('LOL', 'LOL');// true
    Object.is(console, console);// true
    Object.is(null, null);// true
    Object.is('ROFL', 'LOL');// false
    Object.is([], []);// false
    Object.is(0, -0);// false
    Object.is(NaN, 0/0);// true
    
    if (!Object.is)
    {
       // do something
    }
    

相关问题