【问题标题】:Calling a constructor with missing arguments, within a function在函数中调用缺少参数的构造函数
【发布时间】:2016-03-08 19:21:56
【问题描述】:

在 Knockout 的帮助下,我有一个显示项目的简单列表视图。一组 'Things' 被硬编码到一个数组中,并且 Knockout 在页面加载时列出它们。到目前为止它运行良好。

现在,我想添加一个新函数:newFunc()。将在函数中创建一个具有属性但没有名称的新项目。如果用户愿意,可以稍后将该项目添加到列表中。然后,用户可以为项目命名。

:在这种情况下,我如何(或者我可以)使用构造函数'Item'在新函数中创建一个新项目? “Item”函数需要一个参数“item”,但在新函数中,我无法传递参数,因为正在创建新项目并且没有给出名称。我应该如何以不同的方式思考和编码来实现所描述的功能?

任何帮助和提示将不胜感激。

// HTML //

<ul data-bind='foreach: itemList'>
    <li data-bind='text: name'></li>
</ul>

// 脚本 //

var Things = [
    { name: 'name1', property: 'prop1' },
    { name: 'name2', property: 'prop2' },
    ...
];

var Item = function(item) {
    this.name = item.name;
    this.property = item.property;
};

// The new function in Question
var aNewItem;
newFunc = function() {
    // I'd like to create an 'Item' with a given property, but w/o a name.
    aNewItem = new Item(); // ???
    aNewItem.property = 'propertyN'; // **Edit**: also a variable set by user or callback.
};

var viewModel = function {
    self = this;
    self.itemList = ko.observableArray();
    Things.forEach(function(item) {
        self.itemList.push(new Item(item));
    });
};

ko.applyBindings(new viewModel());    

【问题讨论】:

  • 不是先创建item再设置属性,就不能只收集属性,然后调用构造函数吗?否则,您必须删除 item 参数并在实例化后显式设置属性。
  • 是的,我认为它当然可以成为一个解决方案。将数据收集到变量或数组中,稍后根据需要与构造函数一起使用。谢谢你的好建议!我不认为删除 item 参数可能不是最好的解决方案,因为我正在寻找可扩展的东西并从数组 Things 中读取数据。

标签: javascript knockout.js


【解决方案1】:

您可以传递一个只有property 属性的对象。

aNewItem = new Item({
  property: 'propertyN'
});

【讨论】:

  • 这似乎是一个非常简单的解决方案。非常感谢。在这种情况下,aNewItemname 属性是否自动设置为 null 值? (是否有任何文档,我可以阅读关于这样的构造函数的用法?)
  • @Yui 在 JS 中,您有两个“类似 null”的值。 nullundefined (see MDN for more info)。默认情况下,一个变量(或属性)的值是undefined,除非它被明确地赋予另一个值。至于这个构造函数是如何工作的,你所做的只是给它一个具有你需要的属性的对象。 If it looks like a duck and quacks like a duck, it's a duck.
【解决方案2】:

您有几个选择(按照我采用的最佳实践顺序):

在构造函数中使用默认选项

您可以通过在赋值中使用||(或)运算符为构造函数的属性指定默认选项(= 如果|| 之前的值是假的,则分配之后的值)。如果您有一个对象作为参数(这是最简单的),您可以将未传递的项目重新分配给一个空对象,这样可以更轻松地测试其属性。

var Item = function(item) {
    var item = item || {};
    this.name = item.name || '';
    this.property = item.property || 'propertyN';
};

在调用者中使用默认选项 (newFunc)

虽然我认为使用前面显示的默认值更简洁,但也可以在调用构造函数的函数中指定它们:

newFunc = function() {
    aNewItem = new Item({property: 'propertyN'});
};

或者,如果您在构造函数中指定了默认值,您的函数将在其当前状态下正常工作。

仅添加项目参数指定的属性

您还可以选择使用for..in 循环添加项目中给出的所有属性。免责声明:我不建议这样做,因为它使使用构造函数变得毫无意义。

var Item = function(item) {
    var item = item || {};
    for (var prop in item) 
      this[prop] = item[prop];
};

你可以这样做:

newFunc = function() {
    aNewItem = new Item({property: 'propertyN', foo: 'foo'});
    bNewItem = new Item(); 
    console.log(aNewItem.foo); // 'foo'
    console.log(bNewItem['whatever']); // undefined
};

【讨论】:

  • 感谢您提出各种解决方案选项。您的回答非常翔实!使用默认选项构造函数(第一个选项)时,哪些情况被归类为“假”?一个空?
  • @Yui,例如 null、false、undefined、零宽度字符串 ('')、带 '0' 的字符串、数字 0、零宽度数组..MDN还列出了一些。基本上,当您执行 myFalsyValue == false 时将返回 true 的所有内容(不是 3 等于,仅在非严格比较中)。
猜你喜欢
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 2022-06-29
  • 2011-04-27
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多