2011-12-23 43 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