更清晰的方法来隐藏实例中的多个对象缓存

时间:2017-11-03 02:58:58

标签: javascript ecmascript-6 javascript-objects es6-class

我目前正在学习JavaScript,过去几天我一直在阅读一些书籍,但我想对以下内容提供一些帮助。

假设我们有一个名为Label的班级。它的构造函数接受包含一些翻译的data对象。我想在Label实例中“隐藏”这些翻译,并将text属性公开给程序的其余部分。

一种解决方案是使用_active属性引用_translations的转换,getter方法active()返回_active引用的转换,以及setLang()在翻译之间切换的方法。但这会迫使我们总是在标签实例上调用active来获取它的文本,例如label.active.text

(我知道_translations对象并不是真正隐藏的,因为它不是私有的。Label类可能没有多大意义,这是我提出的快速示例,但{_translations 1}} object可以是我们通过API调用获得的翻译缓存。)

肯定有一种更简洁的方法来实现这样的事情,可能会避免标签上的active方法调用。有什么想法吗?

我可以有一个get text(){ return this._active.text },但是如果翻译对象有很多属性呢?

提前致谢!

const data = {
    // these objects could possibly have more properties
    en: {text: 'Text in english.'},
    zh: {text: "Let's imagine this one is in chinese."}
};

class Label {
    constructor(data) {
        this._translations = {};
        for (let lang in data)
            this._translations[lang] = data[lang];
        this._active = this._translations.en;
    }

    get active() {
        return this._active;
    }

    // switch between translations
    // may be used to get translations from an API endpoint
    // if the translation exists, read from _translations cache
    // if not, fetch from server (not implemented)
    setLang(value) {
        return (this._translations[value] &&
            (this._active = this._translations[value])) !== undefined;
    }
}

let label = new Label(data);
console.log(label.active.text);

label.setLang('zh');
console.log(label.active.text);

// I'd like to simply call label.text to return the text

1 个答案:

答案 0 :(得分:0)

在@ Bergi建议使用代理之后,我想出了以下解决我问题的方法。它伴随着使用代理的性能成本,但它足以满足我的需求。



const data = {
  en: {
    text: 'Text in english.',
    color: 'red'
  },
  zh: {
    text: "Let's imagine this one is in chinese.",
    color: 'red in chinese'
  }
};

class Label {
  constructor(data) {
    this._translations = {};
    for (let lang in data)
      this._translations[lang] = data[lang];
    this._active = this._translations.en;
    
    // the 'new' operator passes an emtpy {} to the constructor
    // the constructor returns that object  in the end 
    // the 'this' now is said object (a 'Label')
    
    // then we wrap that object with a prox
    // that proxy redirects all calls to the active label
    return new Proxy(this, {
      get: function(target, name) {
        if (name in target['_active'])
          return target['_active'][name];
        return target[name];
      }
    });
  }

  get active() {
    return this._active;
  }

  hi() {
    console.log(this);
  }

  setLang(value) {
    return (this._translations[value] &&
      (this._active = this._translations[value])) !== undefined;
  }
}

window.label = new Label(data);
console.log(label);
console.log(label.text);
label.setLang('zh');
console.log(label.text);




相关问题