如何在不覆盖现有条目的情况下使用循环将密钥对添加到对象文字?

How to add key pairs to object literals using loop--WITHOUT overriding existing entries?

我正在读取 ul 列表中的输入字段 'name' 和 'value' 属性。没有两个列表具有相同数量的输入,并且 'name' 和 'value' 属性在阅读之前是未知的。

<ul id="options_set1">
    <li><input name="width" value="10" /></li>
    <li><input name="height" value="20" /></li>
    <li><input name="depth" value="5" /></li>
</ul>
<ul id="options_set2">
    <li><input name="finish" value="printed" /></li>
    <li><input name="mounting" value="spacer" /></li>
</ul>

我遍历所有输入,收集 ul id 'options_set_X' 作为我的对象的文字,并且 name:value 对:

var signState = {}; //My object to be populated

var optionSet = '';
var optionName = '';
var optionValue = '';

$("ul li input").each(function() {
  var optionSet = $(this).parent().parent().attr('id');
  signState[optionSet] = {};
  optionName = $(this).attr('name');
  optionValue = $(this).val();
  signState[optionSet][optionName] = optionValue;
});

我无法解决的问题是如何防止此循环替换对象中每个 'optionSet' 文字中的任何现有 name:value 对?

我怀疑是因为我重启了signState[optionSet] = {};文字。

我需要一种在不干扰任何现有关联的情况下为给定文字添加 name:value 对的方法。

我在网上读到的内容都没有涉及这个具体案例,因为我对键名和键值都使用了变量——这使事情变得复杂。

试试这个:

var signState = {};

$("ul li input").each(function() {
    var set, name, value;
    set    = $(this).parent().parent().attr('id');
    name   = $(this).attr('name');
    value  = $(this).val();

    /* Create a fresh object if it doesn't exist, 
     * otherwise assign it the existing one. */
    signState[set] = signState[set] || {};

    /* Again, assign a fresh value if it was undefined or empty 
     * otherwise assign it the existing one. */
    signState[set][name] = signState[set][name] || value;

});

现在如果您设置的值是false0,那么它将被覆盖。如果你不想这样,你必须使用第三运算符来确保你做对了:

signState[set][name] = typeof signState[set][name] !== "undefined"
    ? signState[set][name]
    : value;

三级运算符语法如下:definition = when is true ? this : else this; - 这对此非常有用。

根据 somethinghere 的评论和回答,我得到了完美的结果:

var signState = {}; //My object to be populated

var optionSet = '';
var optionName = '';
var optionValue = '';

$("ul li input").each(function() {
  optionSet = $(this).parent().parent().attr('id');
  signState[optionSet] = {};
  
  //The solution - because it prevents overriding existing literals, so name:value pairs are neatly written to each literal if they don't already exist
  if(!signState[optionSet]) { 
    signState[optionSet] = {};
  }
  //---------
  
  optionName = $(this).attr('name');
  optionValue = $(this).val();
  signState[optionSet][optionName] = optionValue;
});