对象是空的吗?[重复]

2020/09/25 08:41 · javascript ·  · 0评论

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

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

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

    return i;
}

我假设用表示“没有任何属性”。

// 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浏览器,则可以使用Object.getOwnPropertyNames而不是hasOwnProperty循环:

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

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

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

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

编辑:请注意,您可能应该使用ES5解决方案而不是此解决方案,因为近来对ES5的支持非常广泛它仍然适用于jQuery。


简单而跨浏览器的方式是通过使用jQuery.isEmptyObject

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

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

你需要jQuery的。

如果您不介意添加额外的库,则下划线lodash都具有便捷的isEmpty()功能。

_.isEmpty({});

让这个婴儿上床睡觉;经过Node,Chrome,Firefox和IE 9的测试,很明显,对于大多数用例:

  • (for ... in ...)是最快的选择!
  • 空对象的Object.keys(obj).length慢10倍
  • JSON.stringify(obj).length总是最慢的(不足为奇)
  • 在某些系统上,Object.getOwnPropertyNames(obj).length花费的时间比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选项。-否则,使用更通用的(用于... 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);

优雅的方式-使用按键

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

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

function isEmpty( o ) {
    for ( var p in o ) { 
        if ( o.hasOwnProperty( p ) ) { return false; }
    }
    return true;
}
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/

惊讶地看到这么一个基本的JS问题有这么多弱答案...出于以下原因,最佳答案也不是一件好事:

  1. 它生成一个全局变量
  2. 收益trueundefined
  3. 使用for...in本身就非常慢的
  4. 里面的功能for...in没用- false没有hasOwnProperty魔法的回报会很好

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

function isEmpty(value) {
    return Boolean(value && typeof value === 'object') && !Object.keys(value).length;
}

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

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

这有多糟?

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

    return true; // empty
}

无需图书馆。

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

可能有点hacky。你可以试试看

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

不确定此方法是否有任何缺点

快速在线搜索“字典”对象:

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

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

假设您有以下对象:

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
funtion isEmpty(o,i)
{
    for(i in o)
    {
        return!1
    }
    return!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;
  }
}
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
}

可能您可以使用以下决定:

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

我修改了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;

这是我的解决方案

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

芝士

if (Object.getOwnPropertyNames(obj1).length > 0)
{
 alert('obj1 is empty!');
}
本文地址:http://javascript.askforanswer.com/duixiangshikongdemazhongfu.html
文章标签:
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!