【问题标题】:How should I keep a reference to 'options object' in a ES6 instance?我应该如何在 ES6 实例中保留对“选项对象”的引用?
【发布时间】:2015-02-12 12:51:13
【问题描述】:

给定一个如下的 ES6 类,保持对传递给构造函数的数据的引用以便从实例方法中可用的最佳方法是什么?

到目前为止,我发现的最好的方法是手动将每个引用添加到构造函数中的某个实例属性。有没有更清洁/更简单的方法?

class Test {

  constructor( {
    option1 = 1,
    option2 = 2
  } = {} ) {

    // What's the best way to keep a reference to
    // the options on the instance?
    this.options = {
      option1,
      option2
    };
  }

  addOptions() {
    return this.options.option1 + this.options.option2;
  }
}

let t = new Test({
  option1: 5
});

console.log(t.addOptions()); // 7

这是通过 6to5 运行的 above code 的链接。

【问题讨论】:

    标签: javascript ecmascript-6


    【解决方案1】:

    ES6 不允许在类声明中声明原型属性,这有点痛苦……但是,使用 getter 返回默认值可能对您的情况有好处。也许尝试这样的事情:

    class Test {
      get defaults() { return { option1: 1, option2: 2 }; }
    
      constructor(parameters) {
        this.options = Object.assign({}, this.defaults, parameters)
      }
    
      doSomething() {
        return this.options.option1 + this.options.option2;
      }
    }
    
    let test = new Test({
      option1: 5
    });
    
    console.log(test.doSomething());
    

    这是above code running on 6to5 REPL 的链接。如果您想要一个将默认值与继承合并的示例,请查看constructor of this class

    【讨论】:

    • “ES6 不允许实例属性” 呃?那么this.options 是什么?
    • @FelixKling 啊,我应该更清楚一点; ES6 不允许在类声明中声明原型属性:wiki.ecmascript.org/…
    • @AndrewOdri - 谢谢,这里和您链接到的 tungstenjs 存储库中有一些不错的想法。就像你提到的那样,新的类声明语法不允许实例方法有点烦人。我从来不完全确定为什么,但显然是explicitly decided against
    • @JamesAllardice 是的;在这里找到原因的一个很好的讨论:stackoverflow.com/questions/22528967/… 我怀疑真正的原因是它更像是对经典继承的模拟,而不是忠实于原型继承,并且太多的突然变化可能会使开发人员感到困惑不熟悉ES6。希望 ES7 能改变其中的一些行为……
    【解决方案2】:

    由于您正在解构第一个参数并且没有为其命名的引用,this.options = arguments[0] 怎么样?

    如果您不希望外部函数对其进行修改,您可以对其进行深度冻结。

    如果您希望它无法访问,请在模块范围内使用实例键控 WeakMap 来隐藏它们。

    要获取默认值,您可以使用它:

    const defaults = {...}
    
    function(options) {
      this.options = Object.assign({}, defaults, options)
      // now destructure to local vars as needed
      ...
    }
    

    注意:Object.assign 只是一个浅合并。

    【讨论】:

    • arguments[0] 中的对象似乎没有得到例如option2 属性,如果使用默认值而不是传入。否则这将起作用。或者,是否有一种更简洁的方法来为对象参数提供默认值而不对其进行解构?
    猜你喜欢
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2013-09-29
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多