我正在尝试为我正在使用的HTML应用程序创建一个通用的i18n解决方案。我正在寻找使用eval()调用深层嵌套Javascript对象的替代方法:
假设以下HTML示例:
<div id="page1">
<h1 data-i18n="html.pageOne.pageTitle"></h1>
</div>
它是伴侣Javascript(使用jQuery):
var i18n;
i18n = {
html: {
pageOne: {
pageTitle: 'Lorem Ipsum!'
}
}
};
$(document).ready(function () {
$('[data-18n]').each(function () {
var q;
q = eval('i18n.' + $(this).attr('data-i18n'));
if (q) {
$(this).text(q);
}
});
});
有关如何在不使用eval()的情况下访问i18n对象中的“pageTitle”属性的任何建议?我需要保持对象的结构,因此将其布局更改为“平面”解决方案是不可行的。
感谢!!!
答案 0 :(得分:6)
您可以使用括号语法,正如其他人所暗示的那样。但是,您需要在.
分割和迭代:
function lookup(obj, path) {
var keys = path.split('.'),
result = obj;
for (var i = 0, l = keys.length; i < l; i++) {
result = result[keys[i]];
// exit early if `null` or `undefined`
if (result == null)
return result;
}
return result;
}
然后:
q = lookup(i18n, $(this).attr('data-i18n'));
if (q) {
$(this).text(q);
}
答案 1 :(得分:4)
点语法(object.field
)实际上只是object['field']
的语法糖。如果您发现自己正在撰写eval('object.'+field)
,则应该简单地编写object['field']
。在上面的示例中,您可能需要:i18n[$(this).attr('data-i18n')]
。
由于您以一种包含点的方式对属性进行编码,请尝试按点分割,然后迭代字段。例如(这可能会改进):
var fields = $(this).attr('i18n').split('.');
fieldCount = fields.length;
fieldIdx = 0;
var cur = i18n;
while(cur != undefined && fieldIdx > fieldCount) {
cur = cur[fields[fieldIdx++]];
}
您需要进行额外检查以确保处理所有字段,未遇到空字符等。
答案 2 :(得分:1)
您可以在句点上拆分字符串并遍历该对象:
var q = i18n;
$.each($(this).attr('data-i18n').split('.'), function(index, key){
if (q) q = q[key];
});