var tr={};
tr.SomeThing='SomeThingElse';
console.log(tr.SomeThing); // SomeThingElse
console.log(tr.Other); // undefined
tr.get=function(what){
if (tr.hasOwnProperty(what)) return tr[what];
else return what;
};
tr.get('SomeThing') // SomeThingElse
tr.get('Other') // Other
有没有办法让 tr.Other 或 tr['Other'] 以及对象的所有其他未定义属性返回其名称而不是未定义?
三种解决方案:
Proxy
,它旨在完全执行您想要的操作。 始终用一组完整的消息填充您的翻译对象。创建“字典”(服务器端或客户端)时,请始终包含所有需要的键。如果不存在翻译,您可以使用后备语言、消息名称或
undefined
的字符串表示形式 - 您的选择。
但是不存在的属性应该始终意味着“没有这样的消息”而不是“没有可用的翻译”。
使用带有字符串参数的 getter 函数而不是对象属性。该函数可以在内部字典对象中查找消息,并以编程方式处理未命中的消息。
我会推荐一个与字典不同的地图对象,以允许“get”和co作为消息名称:
var translate = (function(){
var dict = {
something: "somethingelse",
...
};
return {
exists: function(name) { return name in dict; },
get: function(name) { return this.exists(name) ? dict[name] : "undefined"; },
set: function(name, msg) { dict[name] = msg; }
};
})();
您可以使用对象初始值设定项为您的属性定义 getter:
var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2;
}
};
console.log(o.a); // 7
console.log(o.b); // 8 <-- At this point the get b() method is initiated.
o.c = 50; // <-- At this point the set c(x) method is initiated
console.log(o.a); // 25
或使用
Object.defineProperties()
:
var o = { a: 0 };
Object.defineProperties(o, {
'b': { get: function() { return this.a + 1; } },
'c': { set: function(x) { this.a = x / 2; } }
});
o.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.b); // Runs the getter, which yields a + 1 or 6
虽然这个解决方案并不完全是您想要的,但Python的collections.defaultdict类的JavaScript实现可能会有所帮助:
var collections = require('pycollections');
var dd = new collections.DefaultDict([].constructor);
console.log(dd.get('missing')); // []
dd.get(123).push('yay!');
console.log(dd.items()); // [['missing', []], [123, ['yay!']]]
代理:
let YOUR_OBJECT = {
key1: 111,
};
/***/
YOUR_OBJECT = new Proxy(YOUR_OBJECT, {
get(obj_origin, key, obj_proxy) {
if (!(key in obj_origin)) {
// console.error(key + ' not found!');
// throw new Error(key + ' not found!');
return key;
}
return Reflect.get(...arguments);
},
});
/***/
console.log(YOUR_OBJECT.key1); // 111
console.log(YOUR_OBJECT.key2); // "key2"
这主要用于测试原因,当您有一个大/旧的代码并且甚至不知道可能需要哪些键时。
如果您从头开始编码,使用代理可能是糟糕设计的标志(它在幕后工作,读者或未来的您可能不清楚),最好使用(作为选项)直接函数
.get(key)
, .set(key, val)
const obj = {
_storage: {
key1: 111,
},
get: function(key) {
if (!(key in this._storage)) {
return key;
}
return this._storage[key];
},
set: function(key, val) {
this._storage[key] = val;
},
};
/***/
console.log(obj.get('key1')); // 111
console.log(obj.get('key2')); // "key2"
您输入的内容多了一点,但为将来节省了很多时间,当您尝试找出发生了什么时。