可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to create a generic i18n solution for a HTML app I'm working in. I'm looking for alternatives to use eval() to call deeply nested Javascript objects:
Suppose the following HTML example:
<div id="page1"> <h1 data-i18n="html.pageOne.pageTitle"></h1> </div>
and it's companion Javascript (using 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); } }); });
Any advices on how to access the "pageTitle" property inside the i18n object without using eval()? I need to keep the object's structure, so changing its layout to a "flat" solution is not feasible.
Thanks!!!
回答1:
You can use bracket syntax, as others have hinted at. But, you'll need to split and iterate at .
:
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; }
Then:
q = lookup(i18n, $(this).attr('data-i18n')); if (q) { $(this).text(q); }
回答2:
The dot syntax (object.field
) is really just syntactic sugar for object['field']
. If you find yourself writing eval('object.'+field)
, you should simply write object['field']
instead. In your example above, you probably want: i18n[$(this).attr('data-i18n')]
.
Since you're encoding your attribute in a way that has dots in it, try splitting it by the dots, and iterating over the fields. For example (this can probably be improved):
var fields = $(this).attr('i18n').split('.'); fieldCount = fields.length; fieldIdx = 0; var cur = i18n; while(cur != undefined && fieldIdx > fieldCount) { cur = cur[fields[fieldIdx++]]; }
You'll want to do additional checking to make sure all of the fields were handled, nulls weren't encountered, etc.
回答3:
You can split the string on the periods and traverse the object:
var q = i18n; $.each($(this).attr('data-i18n').split('.'), function(index, key){ if (q) q = q[key]; });
Demo: http://jsfiddle.net/GsVsr/