我目前正在学习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
答案 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);