Alternatives to eval() for multiple nested objects

匿名 (未验证) 提交于 2019-12-03 02:16:02

问题:

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/



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!