【问题标题】:How to test if JavaScript object is empty?如何测试 JavaScript 对象是否为空?
【发布时间】:2019-03-22 05:10:15
【问题描述】:

我正在尝试测试对象的“空”值。换句话说,如果对象的属性没有值,或者只包含空白值,我们就认为它是空的。

我参考了这篇文章

https://coderwall.com/p/_g3x9q/how-to-check-if-javascript-object-is-empty

并发现了一些有用的东西可以尝试。我最喜欢的这个使用 JSON.stringify 作为一个衬垫。我不确定我完全理解它是如何工作的——我认为当控制台输出一对 {} 大括号时,它意味着它找到了一个对象,但也许还有比这更多的细微差别?

如果可能,我想避免编写自定义函数或导入任何库。

这是一个 MVP 代码示例,演示了我遇到的错误。请注意,最右侧的两个 TD 元素显示为空,但其中包含选项卡。我在这段代码之后包含了我尝试过的“empty-ish”逻辑测试及其结果:

console.clear();

// Set selector values
var selectors = {
  blockSel: "td",
  titleSel: "span",
  urlSel: ""
};

var styles = {
  // reddish text
  style1: "background: bisque; color: brown; font-weight: bold; margin-top: .2em; padding-top: .3em; border-top: solid red 3px;",
  style2: "background:aliceblue;",
  style3: "background:orange;",
  h2: "color: black; font-weight: 700; font-size: 1.2em;"
};

var outObj = {};

// var titles = document.querySelectorAll('#res h3');
var blocks = document.querySelectorAll(selectors.blockSel);

[...blocks].forEach(function(block, i) {
  // Debugging ...
  console.log("%cNumber %s", styles.style1, i);

  console.log("%c\tVALUES:\t\t\t", styles.h2);

  console.log("%cblock.innerText = %s", styles.style2, block.innerText);
  console.log(
    "%cJSON.stringify(block.innerText) = %s",
    styles.style2,
    JSON.stringify(block.innerText)
  );
  console.log(
    "%cJSON.stringify(block.innerText.trim()) = %s",
    styles.style2,
    JSON.stringify(block.innerText.trim())
  );

  console.log("%c\tTESTS:\t\t\t", styles.h2);

  console.log(
    '%cJSON.stringify(block.innerText.trim()) == ""',
    styles.style3,
    JSON.stringify(block.innerText.trim()) == ""
  );
  console.log(
    "%cJSON.stringify(block.innerText) !== undefined",
    styles.style3,
    JSON.stringify(block.innerText) !== undefined
  );
  console.log(
    "%cJSON.stringify(block.innerText) != undefined",
    styles.style3,
    JSON.stringify(block.innerText) != undefined
  );
  console.log(
    '%cJSON.stringify(block.innerText) != ""',
    styles.style3,
    JSON.stringify(block.innerText) != ""
  );
});
body {
  background-position: center bottom;
  padding: 0px;
  margin: 0px;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
  color: #000000;
  background-image: url('images/abstract_background.jpg');
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-color: #00111B;
}

td {
  background: #ffffb3;
  min-width: 13vw;
  text-align: center;
}

#description {
  color: white;
  font-size: 1.2em;
  max-width: 1024px;
}
<div id="description">

  <h2>DESCRIPTION</h2>

  <section>
    <h3>Purpose:</h3>
    <p>This pen demonstrates an issue I'm having with trying test for an "empty-ish" value of an object. In other words, if the object has no values, or contains only whitespace values, let's consider it empty. This isn't working so I'm posting my code to
      help me debug this issue.</p>

    <p>Please open the JavaScript console to view output</p>

    <h3>Errors</h3>

    <ul>
      <li>None.</li>
    </ul>

  </section>

</div>

<table>
  <tr>
    <td valign="top">
      <div id="Archives1_DataList1_ctl40_div1" class="rlvI">
        <div style="width: 175px; float: left; margin-bottom: 5px;">
          <span id="Archives1_DataList1_ctl40_Label2">January 17, 2018</span>
        </div>
        <div>
          <a class="example7" href="/editionviewer/default.aspx?Edition=1ca546d2-2e81-486c-b199-a3d056d157a2" target="_self">
            <img id="Archives1_DataList1_ctl40_Image1" src="https://media.iadsnetwork.com/edition/1964/136061/resized/175_0_1964719d1738-a4a9-46a0-a45e-a1f9aadb7fa7.jpg" style="border-width:0px;">
          </a>
        </div>
      </div>
    </td>
    <td valign="top">
      <div id="Archives1_DataList1_ctl41_div1" class="rlvI">
        <div style="width: 175px; float: left; margin-bottom: 5px;">
          <span id="Archives1_DataList1_ctl41_Label2">January 10, 2018</span>
        </div>
        <div>
          <a class="example7" href="/editionviewer/default.aspx?Edition=cd43c968-1e66-4919-9f97-fc0fe69d749f" target="_self">
            <img id="Archives1_DataList1_ctl41_Image1" src="https://media.iadsnetwork.com/edition/1964/135726/resized/175_0_19644b88f108-6e80-46d6-b7fb-d22f4cebac54.jpg" style="border-width:0px;">
          </a>
        </div>
      </div>
    </td>
    <td valign="top">
      <div id="Archives1_DataList1_ctl42_div1" class="rlvI">
        <div style="width: 175px; float: left; margin-bottom: 5px;">
          <span id="Archives1_DataList1_ctl42_Label2">January 3, 2018</span>
        </div>
        <div>
          <a class="example7" href="/editionviewer/default.aspx?Edition=fd6fb6f4-6b86-4489-a65f-eeb41d64eade" target="_self">
            <img id="Archives1_DataList1_ctl42_Image1" src="https://media.iadsnetwork.com/edition/1964/135385/resized/175_0_1964a8b1cc88-08f4-49f0-ace1-ca84b8a26d55.jpg" style="border-width:0px;">
          </a>
        </div>
      </div>
    </td>
    <td></td>
    <td></td>
  </tr>
</table>

这是第 3 和第 4 个 TD 的屏幕截图。如您所见,第 3 项显示了一个 innerText 值,但第 4 项没有文本,只有一个 TAB 字符。但是,它们都测试相同。

警告:

此帖子 How do I test for an empty JavaScript object? 被建议为可能重复。我希望它是,但它不是。此外,我尝试了最高评价的答案,使用 Pre-ECMA 5 解决方案以获得最大的兼容性,但无济于事。实现该功能不起作用。我很快就会更新一个最低限度的可验证代码......

代码尝试 2:

在这次尝试中,我尝试了两个不同的函数来测试一个空对象。就像我已经说过的,我的对象不一定是空的,但它们可能包含空格字符。我已经从第一个示例中消除了很多调试,以使其更精确和更小。

这是我使用的函数

前 ECMA 5

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

    return JSON.stringify(obj) === JSON.stringify({});
} 

ECMA 5

function isEmpty2(obj) {
  if ( Object.keys(obj).length === 0 && obj.constructor === Object ) {
    return true;
  }

  return false;
}

同样,这些函数都不起作用。这是此尝试的完整代码示例:

console.clear();

var outObj = {};

var blocks = document.querySelectorAll('td');

[...blocks].forEach(function(block, i) {
  // Debugging ...
  console.log("%cNumber %s", styles.style1, 1+i);

  console.log(block);
  console.log("%cisEmpty(block) = %s", styles.style4, isEmpty(block));
  console.log("%cisEmpty2(block) = %s", styles.style4, isEmpty2(block));
  
});

/* isEmpty() */
function isEmpty(obj) {
    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            return false;
    }

    return JSON.stringify(obj) === JSON.stringify({});
} 

/* isEmpty2() */
function isEmpty2(obj) {
  if ( Object.keys(obj).length === 0 && obj.constructor === Object ) {
    return true;
  }
  
  return false;
}
body
{
    background-position: center bottom;
    padding: 0px;
    margin: 0px;
    font-family: Arial, Helvetica, sans-serif;
    font-size: 12px;
    color: #000000;
    background-image: url('images/abstract_background.jpg');
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-color: #00111B;
}

td {
  background: #ffffb3;
  min-width: 13vw;
  text-align: center;
}

#description {
  color: white;
  font-size: 1.2em;
  max-width: 1024px;
}
<table>
  <tr>
    <td valign="top">
      <div id="Archives1_DataList1_ctl40_div1" class="rlvI">
        <div style="width: 175px; float: left; margin-bottom: 5px;">
          <span id="Archives1_DataList1_ctl40_Label2">January 17, 2018</span>
        </div>
        <div>
          <a class="example7" href="/editionviewer/default.aspx?Edition=1ca546d2-2e81-486c-b199-a3d056d157a2" target="_self">
               <img id="Archives1_DataList1_ctl40_Image1" src="https://media.iadsnetwork.com/edition/1964/136061/resized/175_0_1964719d1738-a4a9-46a0-a45e-a1f9aadb7fa7.jpg" style="border-width:0px;">
               </a>
        </div>
      </div>
    </td>
    <td valign="top">
      <div id="Archives1_DataList1_ctl41_div1" class="rlvI">
        <div style="width: 175px; float: left; margin-bottom: 5px;">
          <span id="Archives1_DataList1_ctl41_Label2">January 10, 2018</span>
        </div>
        <div>
          <a class="example7" href="/editionviewer/default.aspx?Edition=cd43c968-1e66-4919-9f97-fc0fe69d749f" target="_self">
               <img id="Archives1_DataList1_ctl41_Image1" src="https://media.iadsnetwork.com/edition/1964/135726/resized/175_0_19644b88f108-6e80-46d6-b7fb-d22f4cebac54.jpg" style="border-width:0px;">
               </a>
        </div>
      </div>
    </td>
    <td valign="top">
      <div id="Archives1_DataList1_ctl42_div1" class="rlvI">
        <div style="width: 175px; float: left; margin-bottom: 5px;">
          <span id="Archives1_DataList1_ctl42_Label2">January 3, 2018</span>
        </div>
        <div>
          <a class="example7" href="/editionviewer/default.aspx?Edition=fd6fb6f4-6b86-4489-a65f-eeb41d64eade" target="_self">
               <img id="Archives1_DataList1_ctl42_Image1" src="https://media.iadsnetwork.com/edition/1964/135385/resized/175_0_1964a8b1cc88-08f4-49f0-ace1-ca84b8a26d55.jpg" style="border-width:0px;">
               </a>
        </div>
      </div>
    </td>
    <td></td>
    <td></td>
  </tr>
</table>

【问题讨论】:

  • 依赖JSON.stringify()的问题是不是所有的对象都可以渲染成JSON,会抛出异常。我认为根据您对“空”的定义编写一个“自定义函数”来检查会更加稳定。
  • "如果可能,我想避免编写自定义函数或导入任何库。"如果没有原生的 JS 函数可以做到这一点,你将不得不做其中之一。
  • 您提到了一个空的“对象”,但又提到了检查&lt;td&gt; 的内容。后者可以使用document.querySelectorAll('td:empty')(即`:empty' pseudo class)找到。
  • @codeepic 给我几分钟时间检查一下,以确定内容是否相同或名称是否相似。如果它是一个真正的重复,我会删除我的帖子,但我不想过早地删除它,因为我可能无法根据 Stack Overflow 缓存数据库服务器来添加它。

标签: javascript undefined javascript-objects equality is-empty


【解决方案1】:

!!Object.getOwnPropertyNames({}).length => false

!!Object.getOwnPropertyNames({a: 'abc'}).length => true

=============================================

Object.getOwnPropertyNames({}).length => 0

Object.getOwnPropertyNames({a: 'abc'}).length => 1

【讨论】:

  • 感谢您的回答。我会花一些时间评估它是否能解决我最初的问题。
猜你喜欢
  • 2014-12-24
  • 2013-10-10
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 1970-01-01
  • 2020-10-25
相关资源
最近更新 更多