0

我将一个大的“选项”对象传递给我在 JavaScript 中实例化的另一组对象。问题是,这些“选项”中的极少数必须从一个对象更改为另一个对象。制作一个完全独立的选项变量,改变许多选项中的一个,感觉很愚蠢。我也不认为我可以只更改同一“选项”对象上的选项,因为所有对象都将引用相同的“选项”。

下面是相关代码。

    for (var i = 0; i < invoices.length; i++) {

        var ura_original_column = { "column" : "ura_ppa_original",
                                    "on_update" : [format_ura],
                                    "display" : "URA" };

        if (invoices[i]["type"] == "P") {
            ura_original_column = { "column" : "ura_original",
                                    "on_update" : [format_ura],
                                    "display" : "URA" };
        }

        var options = { template_table  : "template_table",
                        template_total  : "template_total",
                        template_row    : "template_row",
                        template_text   : "template_text",
                        template_select : "template_select",
                        packet_id       : <?val=packet["packet_id"]?>,
                        products        : <?val=json.dumps(products)?>,
                        allow_new_rows  : <?val=json.dumps(packet["status"] not in api.NON_MODIFIABLE_STATUS)?>, 
                        on_table_focus  : on_table_focus,
                        on_row_update   : on_row_update,
                        on_new_row      : on_new_row,
                        columns : [{"column" : "product_code", 
                                    "display" : "Product"},
                                   {"column" : "transaction_type",
                                    "display" : "FFSU/MCOU",
                                    "editor" : "selectedit",
                                    "options" : ["FFSU", "MCOU"]},
                                    ura_original_column,
                                   {"column" : "ura_current",
                                    "display" : "Calculated URA"},
                                   {"column" : "units_current",
                                    "display" : "Current Units",
                                    "on_update" : [format_units],
                                    "show_total" : true},
                                   {"column" : "amount_claimed", 
                                    "display" : "Amt Claimed",
                                    "on_update" : [format_currency],
                                    "show_total" : true},
                                   {"column" : "scripts_current",
                                    "display" : "Scripts",
                                    "on_update" : [format_scripts],
                                    "show_total" : true},
                                   {"column" : "amount_medi_reimbursed", 
                                    "display" : "MEDI Amt", 
                                    "on_update" : [format_currency],
                                    "show_total" : true},
                                   {"column" : "amount_non_medi_reimbursed", 
                                    "display" : "Non-MEDI Amt", 
                                    "on_update" : [format_currency],
                                    "show_total" : true},
                                   {"column" : "amount_total_reimbursed", 
                                    "display" : "Total Amt", 
                                    "on_update" : [format_currency],
                                    "show_total" : true}]}

        var invoice_id = invoices[i]['invoice_id'];
        var transactions = transactions_by_invoice[invoice_id];
        var table = new Table.Table("invoice_" + invoice_id, options, transactions);

        tables.push(table);
    }
});

因此,在这个巨大的选项结构中,只有“ura_original_column”发生了变化。这可能是最好的方法,但感觉有点像黑客。

有人有更优雅的建议吗?

感谢您花时间查看。

4

1 回答 1

1

您可以使用 newObject.create创建一个新对象,该对象仅具有不同的选项,但由具有所有其他选项的原型支持。(这是一个 ES5 功能,但您可以创建一个提供主要功能的版本,或者使用“ES5 shim”项目提供的功能,包括您需要的部分;在 ES5 之前的环境中完全创建是不可能的Object.create,但你不需要全部。)

看起来像这样:

var mainOptions = { /* ...bit list of main options... */ };

for (index = 0; index < limit; ++index) {
    theseOptions = Object.create(mainOptions);
    theseOptions.column = "new column name";
    doTheThing(theseOptions);
}

你最终得到的是一个对象,它只有你更改的属性,但如果被要求提供任何其他属性,它将从主选项原型返回值。

这是一个独立的示例:Live copy | 来源

(function() {

  // Get a `create` function that acts a bit like
  // `Object.create` even if `Object.create` isn't
  // there
  var objectCreate = (function() {
    if (Object.create) {
      return Object.create;
    }

    function ctor() { }

    return function(proto) {
      var rv, key;

      ctor.prototype = proto;
      rv = new ctor();
      ctor.prototype = undefined;

      return rv;
    };
  })();


  var mainOptions = {
    option1: "Main option 1",
    option2: "Main option 2",
    option3: "Main option 3"
  };

  var index;
  var theseOptions;

  for (index = 0; index < 4; ++index) {
    theseOptions = objectCreate(mainOptions);
    theseOptions.option2 = "Special option 2 for index " + index;

    displayOptions(index, theseOptions);
  }
  display("Options passed to function");

  function displayOptions(index, options) {
    // Do it *later* so we know we weren't just
    // doing it before the object got updated
    setTimeout(function() {
      display("Options for index " + index + ":");
      display(options.option1);
      display(options.option2);
      display(options.option3);
    }, 0);
  }

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = String(msg);
    document.body.appendChild(p);
  }
})();

同样,重要的是要理解objectCreate给定的 ifObject.create不存在并不是真正的完整垫片Object.create。完成我们想要完成的部分就足够了。

于 2012-05-18T15:02:45.407 回答