【问题标题】:How to check if object has any properties in JavaScript?如何检查对象是否在 JavaScript 中有任何属性?
【发布时间】:2010-04-20 06:44:17
【问题描述】:

假设我声明

var ad = {}; 

如何检查此对象是否包含任何用户定义的属性?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您可以使用内置的Object.keys 方法获取对象上的键列表并测试其长度。

    var x = {};
    // some code where value of x changes and than you want to check whether it is null or some object with values
    
    if(Object.keys(x).length){
     // Your code here if x has some properties  
    }
    

    【讨论】:

    • 就在这里是正确答案。上面接受的答案是一种解决方法,并且比仅检查键的数量更昂贵;这让更有意义
    • Object.keys("mystring");也产生我认为不受欢迎的密钥。我认为这个答案是不完整的。
    • @MikedeKlerk 请仔细阅读它不是 Object.keys("mystring");它是 Object.keys(objectVariableName) ,它将返回对象中所有键的数组。 ex : { 'x' : 'abc', 'y' : 'def' } 它将是 ['x' , 'y']
    • @DhavalChaudhary 感谢您对我的评论的回复。当我尝试此代码var str = "MyString"; Object.keys(str); 时,控制台为每个字符输出 8 个键,从 0 到 7。还是我还是不明白答案。
    • @MikedeKlerk 但它是对象而不是字符串的唯一解决方案,请参考问题。
    【解决方案2】:

    做一个简单的函数怎么样?

    function isEmptyObject(obj) {
      for(var prop in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, prop)) {
          return false;
        }
      }
      return true;
    }
    
    isEmptyObject({}); // true
    isEmptyObject({foo:'bar'});  // false
    

    直接在Object.prototype 上调用hasOwnProperty 方法只是为了增加一点安全,想象一下使用普通的obj.hasOwnProperty(...) 调用:

    isEmptyObject({hasOwnProperty:'boom'});  // false
    

    注意: (for the future) 上述方法依赖于for...in 语句,并且该语句仅迭代可枚举属性,在目前实施最广泛的 ECMAScript 标准(第 3 版)中,程序员没有任何方法可以创建不可枚举的属性。

    但是现在ECMAScript 5th Edition 改变了这种情况,我们能够创建不可枚举、不可写或不可删除的属性,因此上述方法可能会失败,例如:

    var obj = {};
    Object.defineProperty(obj, 'test', { value: 'testVal', 
      enumerable: false,
      writable: true,
      configurable: true
    });
    isEmptyObject(obj); // true, wrong!!
    obj.hasOwnProperty('test'); // true, the property exist!!
    

    此问题的 ECMAScript 5 解决方案是:

    function isEmptyObject(obj) {
      return Object.getOwnPropertyNames(obj).length === 0;
    }
    

    Object.getOwnPropertyNames 方法返回一个Array,其中包含所有对象的自己的属性的名称,是否可枚举,浏览器供应商现在正在实施这种方法,它已经在 Chrome 5 Beta 和最新的 WebKit Nightly Builds 上。

    Object.defineProperty 也可用于这些浏览器和最新的 Firefox 3.7 Alpha 版本。

    【讨论】:

    • Object.prototype.hasOwnProperty.call(obj, prop) 比 obj.hasOwnProperty(prop) 有什么优势?
    • @Casey,已编辑,如果一个对象覆盖了hasOwnProperty 属性,函数可能会崩溃......我知道我有点偏执......但有时你不知道你的代码会使用什么样的环境,但是你知道你要使用什么样的方法……
    • +1 回答这个问题......以及未来的其他问题! :)
    • 请注意,IE 中还有一个错误,如果您有一个名称与Object.prototype 中的不可枚举属性匹配的属性,它不会被for...in 枚举。所以isEmptyObject({toString:1}) 会失败。这是您不能相当Object用作通用映射的不幸原因之一。
    • @MichaelMartin-Smucker—keys 只返回可枚举的自己的属性,所以不适合这里。
    【解决方案3】:

    您可以按如下方式遍历对象的属性:

    for(var prop in ad) {
        if (ad.hasOwnProperty(prop)) {
            // handle prop as required
        }
    }
    

    重要的是使用hasOwnProperty()方法,判断对象是否具有指定属性作为直接属性,而不是继承自对象的原型链。

    编辑

    来自 cmets: 您可以将该代码放在一个函数中,并使其在到达有注释的部分时立即返回 false

    【讨论】:

    • 嗨丹尼尔,实际上我正在寻找一种设备来检查对象是否包含用户定义的属性。不检查特定属性是否存在。
    • @Ricky:您可以将该代码放在一个函数中,并使其在到达有注释的部分时立即返回 false。
    • 我认为这些天使用Object.keys 是最简单的:var a = [1,2,3];a.something=4;console.log(Object.keys(a)) 因为它已经是 ECMA 5 的一部分,您可以放心地对其进行填充:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 请注意,“这些天”在 ES5 中,本机对象可以拥有不可枚举的自身属性,例如Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
    • 这个解决方案是一种检查存在的键的方法,但真正、有效和最正确的答案是使用 Object.keys(x).length。你不需要自己做一个函数,一个已经存在了!
    【解决方案4】:

    使用 jQuery 你可以使用:

    $.isEmptyObject(obj); // Returns: Boolean
    

    从 jQuery 1.4 开始,此方法检查对象本身的属性和从原型继承的属性(因为它不使用 hasOwnProperty)。

    借助现代浏览器(IE9+、FF4+、Chrome5+、Opera12+、Safari5+)中的ECMAScript 5th Edition,您可以使用内置的Object.keys 方法:

    var obj = { blah: 1 };
    var isEmpty = !Object.keys(obj).length;
    

    或普通的旧 JavaScript:

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

    【讨论】:

      【解决方案5】:

      最新的浏览器(和 node.js)支持 Object.keys() ,它返回一个包含对象文字中所有键的数组,因此您可以执行以下操作:

      var ad = {}; 
      Object.keys(ad).length;//this will be 0 in this case
      

      浏览器支持:Firefox 4、Chrome 5、Internet Explorer 9、Opera 12、Safari 5

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

      【讨论】:

        【解决方案6】:

        如果您使用 underscore.js,那么您可以使用 _.isEmpty 函数:

        var obj = {};
        var emptyObject = _.isEmpty(obj);
        

        【讨论】:

        【解决方案7】:

        如果你愿意使用lodash,可以使用some方法。

        _.some(obj) // returns true or false
        

        看这个小jsbinexample

        【讨论】:

        • var x = [1,2] // true
        • @damionjn 我将您的代码添加到示例中。我看到你的观点,数组返回了错误的答案,但是 OP 最初将一个变量声明为一个对象,所以我相信它可以假设这一点。上面有一个答案,它使用下划线 isEmpty 方法(lodash 有相同的方法)。该答案具有完全相同的问题。如果你给 isEmpty 一个非空数组,你也会得到错误的结果。
        • 很公平,但我们应该提供涵盖所有基础的答案,以确保最佳实践。你是对的,我没有任何批评就通过了他的回答。只是对于任何路过的人,这不是专用于对象的方法。 _.some([1, 2]) // true一定要先检查:stackoverflow.com/a/13356338/1922747
        【解决方案8】:
        for (var hasProperties in ad) break;
        if (hasProperties)
            ... // ad has properties
        

        如果您必须确保安全并检查对象原型(这些是由某些库添加的,默认情况下不存在):

        var hasProperties = false;
        for (var x in ad) {
            if (ad.hasOwnProperty(x)) {
                hasProperties = true;
                break;
            }
        }
        if (hasProperties)
            ... // ad has properties
        

        【讨论】:

        • 在您的解决方案中,没有过滤不需要的原型属性,这意味着在使用像 Prototype.js 这样的库或没有经验的用户向对象添加额外的原型属性时,它可能会出现异常行为。在此页面上查看 Daniels 解决方案。
        • 您不必使用库或没有经验来扩展对象的原型。 一些有经验的程序员一直都在这样做。
        【解决方案9】:
        for(var memberName in ad)
        {
          //Member Name: memberName
          //Member Value: ad[memberName]
        }
        

        Member表示Member属性,成员变量,随便你怎么称呼>_>

        以上代码将返回所有内容,包括 toString... 如果只想查看对象的原型是否被扩展:

        var dummyObj = {};  
        for(var memberName in ad)
        {
          if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
          //Member Name: memberName
          //Member Value: ad[memberName]
        
        }
        

        注意 A:我们检查虚拟对象的成员是否与我们的测试对象的成员具有相同的类型。如果是extend,dummyobject的成员类型应该是“undefined”

        【讨论】:

        • 嗨,我能知道一个对象是否包含属性吗?谢谢
        • 在您的解决方案中,没有过滤不需要的原型属性,这意味着在使用 Prototype.js 之类的库或没有经验的用户向对象添加额外的原型属性时,它可能会出现异常。
        • 在此页面上查看 Daniels 解决方案 - 它不易出错!
        • 您的第一个代码块根本没有涵盖它。如果我将变量添加到未定义的“广告”对象,则第二个代码块会出现异常。真的,看看 Daniels 的答案,它是唯一正确的答案,而且速度很快,因为它使用了一个名为“hasOwnProperty”的本机实现。
        • @Ricky:如果你想检查一个对象是否包含属性,你可以简单地使用我回答中的例子:stackoverflow.com/questions/2673121/…。如果代码到达注释,您的对象将没有任何直接属性。如果没有,它会。
        【解决方案10】:
        var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
        // as of this line hasAnyProps will show Boolean whether or not any iterable props exist
        

        简单,适用于所有浏览器,尽管从技术上讲它是对象上所有键的循环,但它确实循环遍历它们...要么是 0 并且循环不运行或者有一些,它在第一个之后就中断了(因为我们要检查的是是否有任何......那么为什么要继续?)

        【讨论】:

          【解决方案11】:

          ES6函数

          /**
           * Returns true if an object is empty.
           * @param  {*} obj the object to test
           * @return {boolean} returns true if object is empty, otherwise returns false
           */
          const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0
          
          

          例子:

          
          let obj = "this is an object with String constructor"
          console.log(pureObjectIsEmpty(obj)) // empty? true
          
          obj = {}
          console.log(pureObjectIsEmpty(obj)) // empty? true
          
          obj = []
          console.log(pureObjectIsEmpty(obj)) // empty? true
          
          obj = [{prop:"value"}]
          console.log(pureObjectIsEmpty(obj)) // empty? true
          
          obj = {prop:"value"}
          console.log(pureObjectIsEmpty(obj)) // empty? false
          
          

          【讨论】:

            【解决方案12】:

            当确定对象是用户定义的对象时,确定 UDO 是否为空的最简单方法是以下代码:

            isEmpty=
            /*b.b Troy III p.a.e*/
            function(x,p){for(p in x)return!1;return!0};
            

            尽管这种方法(本质上)是一种演绎方法,但它是最快的,也是可能的最快的。

            a={};
            isEmpty(a) >> true
            
            a.b=1
            isEmpty(a) >> false 
            

            附言: !不要在浏览器定义的对象上使用它。

            【讨论】:

            • ...返回 0;返回 1};会一样吗?
            • @pike no, return!1;return!0 与 return false;return true 相同
            • 这是最短代码的答案。 isEmpty=(x,p)=>{for(p in x)return!1;return!0};
            【解决方案13】:

            您可以使用以下内容:

            双响!!属性查找

            var a = !![]; // true
            var a = !!null; // false
            

            hasOwnProperty 这是我以前用过的东西:

            var myObject = {
              name: 'John',
              address: null
            };
            if (myObject.hasOwnProperty('address')) { // true
              // do something if it exists.
            }
            

            但是,JavaScript 决定不保护方法的名称,因此它可能会被篡改。

            var myObject = {
              hasOwnProperty: 'I will populate it myself!'
            };
            

            myObject 中的道具

            var myObject = {
              name: 'John',
              address: null,
              developer: false
            };
            'developer' in myObject; // true, remember it's looking for exists, not value.
            

            类型

            if (typeof myObject.name !== 'undefined') {
              // do something
            }
            

            但是,它不检查 null。

            我认为这是最好的方法。

            in 运算符

            var myObject = {
              name: 'John',
              address: null
            };
            
            if('name' in myObject) {
              console.log("Name exists in myObject");
            }else{
              console.log("Name does not exist in myObject");
            }
            

            结果:

            名称存在于我的对象中

            这里有一个链接,可以更详细地了解 in 运算符:Determining if an object property exists

            【讨论】:

              【解决方案14】:

              答案很晚,但这是您可以使用原型处理它的方式。

              Array.prototype.Any = function(func) {
                  return this.some(func || function(x) { return x });
              }
              
              Object.prototype.IsAny = function() {
                  return Object.keys(this).Any();
              }
              

              【讨论】:

                【解决方案15】:

                Object.hasOwn 是一种新的静态方法(并非所有浏览器都完全支持),它检查指定对象是否具有指定的属性作为他自己的属性,如果是则返回 true。如果该属性是继承的或该对象上不存在,它将返回 false。

                您可以遍历对象属性并检查它们是否确实是自己的属性

                for (let property in ad) {
                   if (Object.hasOwn(ad, property)) {
                    // handle your code for object own properties here
                  }
                }   
                

                更多关于Object.hasOwn - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/

                此处的浏览器兼容性 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility

                【讨论】:

                • 尚无 Safari(iOS 或 Macos)支持 =(
                【解决方案16】:

                我不确定这是否是一个好方法,但我使用此条件来检查对象是否具有任何属性。可以很容易地转化为函数。

                const obj = {};
                    
                if(function(){for (key in obj){return true}return false}())
                {
                  //do something;
                }
                else
                {
                  //do something else;
                }
                    
                //Condition could be shorted by e.g. function(){for(key in obj){return 1}return 0}()
                

                【讨论】:

                  【解决方案17】:

                  这个怎么样?

                  var obj = {},
                  var isEmpty = !obj;
                  var hasContent = !!obj
                  

                  【讨论】:

                  • 这个答案没有回答问题。 OP 询问对象是否包含用户定义的属性 - 您的答案检查对象本身是否将转换为布尔值。
                  • ...我后来也意识到詹姆斯已经在他的回答中包含了这个选项。对不起,伙计们。
                  猜你喜欢
                  • 2010-09-13
                  • 2017-01-09
                  • 2012-04-16
                  • 2016-01-17
                  • 1970-01-01
                  • 2014-01-01
                  • 1970-01-01
                  • 2014-05-08
                  相关资源
                  最近更新 更多