2011-12-23 44 views
4

不知道该怎么说。带变量的Javascript点符号

我想使用一个变量来确定钻入对象返回值的距离。

var target = "level1.level2.var"; 
var myObject = { 
        level1: { 
         level2: { 
          var: 'value' 
         } 
        } 
       } 
var returnVal = myObject.target; 

这怎么办?显然这不会起作用。是否有其他可能?

我想我可能会爆炸目标变量,然后循环每个级别,但认为我会问,看看有没有更容易忽略的方法。

+0

'r eturnVal = eval(“myObject。”+ target)'? – 2011-12-23 21:10:13

+0

@Shiplu:是的,但是使用'eval'。 – 2011-12-23 21:11:31

+0

只要你没有传递用户输入或检查字符串的安全。 – 2011-12-23 21:13:26

回答

9

您可以使用此功能:

function get_property_from_target(obj, target){ 
    var arr = target.split('.'); 
    for(var i = 0; i < arr.length; i++){ 
     if(obj) 
      obj = obj[arr[i]]; 
    } 
    return obj; 
} 

然后调用它像:

get_property_from_target(myObject, target); 

我的函数重命名为更好的东西了。

也请不要命名对象属性var因为这是一个JavaScript中的关键字,它可能会让人困惑,我不确定它会一直按照您期望的方式工作,或者它只会导致一些错误浏览器。

+0

将if(obj)'添加到循环中,以便在发送无效目标时返回undefined,而不是发出错误。 – Paulpro 2011-12-23 21:16:31

1

除了编写代码将目标分割为.之外,没有办法,那么对于每个令牌,只要“路径”有效,就向下钻取该对象。

1

我会做什么(也许不是最好的,但它会工作),这是你的建议。展开变量,然后转到该级别。

var target = "level1.level2.var"; 
target = target.split('.'); 

var returnVal = myObject; 
for(var i=0,len=target.length; i<len; i++){ 
    returnVal = returnVal[target[i]]; 
} 

console.log(returnVal); // value 
4

更容易?当然,使用eval

var obj = eval('myObject.' + target); 

这不是一个真正的严肃的回答,虽然。你不应该使用eval那么好的代码。唯一的其他方式,据我所知,但是,是循环为你描述:

var items = target.split('.'); 
var obj = myObject; 
var i; 

for(i = 0; i < items.length; i++) { 
    obj = obj[items[i]]; 
} 

或者,用正则表达式黑客:

var obj = myObject; 
target.replace(/[^\.]+/g, function(m) { 
    obj = obj[m]; 
}); 

无论如何,你现在可以使用obj

+0

'/[^\.]+/ g.exec('level1.level2.var');''返回'['level1']'。为什么不使用'target.split('。')'? – 2011-12-23 21:13:58

+1

@火箭:是的,我进入了一个解决方案的一半:)我已经编辑它,但再次阅读。 – Ryan 2011-12-23 21:14:38

+0

+1,这是一个整洁的小'.replace'技巧。 – 2011-12-23 21:16:22

2

我可以看到这样做的方法有两种:

  • 使用eval()(皱眉,因为evalevil):

    var returnVal = eval('myObject.' + target); 
    
  • 使用循环:

    var split = target.split('.'); 
    var newTarget = myObject; 
    
    for (var i = 0; i < split.length; i++) { 
        newTarget = newTarget[split[i]]; 
    } 
    
+0

我建议不要使用'eval',但我想这是一个解决方案。 – 2011-12-23 21:12:29

+0

我会补充说它不是最佳的。 – Blender 2011-12-23 21:13:09