2013-04-09 77 views
1

有沒有辦法在不使用eval()的情況下執行以下操作?檢查對象是否定義在對象名字符串中

以下函數接受字符串數組,其中的字符串是對象名稱。我遍歷它們以確保它們都不是未定義的。我希望能夠做到這一點,而無需使用eval()

function hasMissingDependencies(dependencies) { 
    var missingDependencies = []; 

    for (var i = 0; i < dependencies.length; i++) { 
     if (eval('typeof ' + dependencies[i]) === 'undefined') { 
      missingDependencies.push(dependencies[i]); 
     } 
    } 

    if (missingDependencies.length > 0) { 
     return true; 
    } 

    return false; 
} 

有了這個,我能夠通過類似下面的,並得到了我想要的:

alert(hasMissingDependencies(['App.FooObject', 'App.BarObject'])); 

我寧願不使用eval(),但還沒有找到另一種方法來檢查對象名稱作爲字符串傳遞時是否未定義對象。

+0

爲什麼你需要將它們作爲字符串傳遞? – 2013-04-09 19:04:08

+0

我不知道另一種方法來傳遞**可能未定義到另一個函數的對象名稱。例如,調用'hasMissingDependencies(App.FooObject,App.BarObject)'如果其中任何一個對象沒有被定義,就會在它進入函數之前拋出一個錯誤。我錯過了什麼嗎? – Jared 2013-04-09 19:11:29

+0

你從哪裏通過它?你可以看到我的答案是一個可能的解決方案,但是在你傳遞它們之前檢查它們是否存在,然後傳遞null或者其他一些值,如果不存在,會更簡單。 – 2013-04-09 19:13:24

回答

5

假設這些都是全局變量(即不是一個內部函數範圍內定義),你可以在句點上分割並使用括號表示法。

function isDefined(name, obj){ 
    if(!obj){ 
     obj = window; 
    } 
    var pathArr = name.split("."); 
    obj = obj[pathArr.splice(0,1)]; 
    if(typeof obj !== undefined){ 

    return pathArr.length ? isDefined(pathArr.join("."),obj): true; 
    } 

    return false; 


} 

需要注意的是,除非你想寫一個requireJS更換,這是幾乎總是一個壞主意,但。檢查值是否存在於你調用該函數的上下文中,如果它們存在,則傳入值,否則傳入null/undefined /一些默認值。如果您不控制傳遞的上下文,請詢問對象,然後檢查它們是否已定義。

+0

已注意。謝謝您的幫助。我打算將這個答案標記爲可接受的,因爲它是最容易遵循的,但我鼓勵任何人使用此線程查看@dystroy的答案,以獲得更簡潔的版本。 – Jared 2013-04-09 19:33:30

2

您似乎想要檢查名稱在您的數組中的全局變量是否已定義。

您可以構建一個簡單的函數來獲取這些變量:

function getVar(name) { 
    var v = window, path=name.split('.'); 
    while (path.length>0 && v) v = v[path.shift()]; 
    return v; 
} 

這樣可以讓您測試

if (typeof getVar(dependencies[i]) === 'undefined') 
+1

這也是我的想法。儘管如此,這對他的命名空間不起作用。即使App.FooObject存在,window ['App.FooObject']也會返回undefined – 2013-04-09 19:06:48

+1

@ ben336我還沒有理解這個需求。我認爲現在更好, – 2013-04-09 19:12:59

+2

是的,比我的版本更清潔。 Upvoted。雖然可能值得一提的答案是,這通常不是一個好主意:) – 2013-04-09 19:17:06

相關問題