2011-12-02 62 views
0

我有一個函數想要訪問一個全局變量,其名稱作爲字符串參數到達。這是現在的樣子,使用eval:試圖避免eval從窗口對象獲取數組元素

function echoVar(whichone){ 
    document.write(eval(whichone)); 
} 

我想我只是用窗口[]語法和有這樣的:

function echoVar(whichone) { 
    document.write(window[whichone]); 
} 

如果我創建一個變種,並調用它像這樣,它的文檔寫ABC預期:

var abc = "ABC"; 
echoVar("abc"); 

如果我要訪問的變種是雖然一個數組元素,這是行不通的:

var def = ["DEF"]; 
echoVar("def[0]"); //fails with undefined 

很明顯,這實際上是執行window [def [0]],它正確地給出了未定義的(因爲沒有稱爲DEF的變量)。我真正想要發生的是它執行窗口[「def」] [0]。

我知道要做到這一點的唯一方法就是用「[」作爲分隔符,然後使用split [0]作爲窗口索引和split [1]上的parseInt來分割哪個參數得到的索引,像這樣:

function echoVar(whichone){ 
    if(whichone.indexOf("[")==-1){ 
    document.write(window[whichone]); 
    } 
    else{ 
    var s = whichone.split("["); 
    var nam = s[0]; 
    var idx = parseInt(s[1]); 
    document.write(window[nam][idx]); 
    } 
} 

我可以忽略一些明顯的東西嗎?我寧願保持評估,也不願意做所有這些。

+0

難道沒有辦法讓價值以更好的方式傳遞嗎? –

+0

這是一個實驗還是您正在嘗試將此技術用於生產用途? –

+0

我正在使用一個庫(如jquery,但不是jQuery),它恰好以這種方式傳遞了var的名稱。可悲的是我不能改變我收到的東西,只是我如何使用它。 – Dee2000

回答

1

如果你不喜歡在你的代碼使用eval,你總是可以做到這一點:

function echoVar(whichone) { 
    document.write(Function("return " + whichone)()); 
} 
+0

我可能錯了,但不是在幕後使用eval嗎?很難想象沒有它會如何執行。而是像document.write(23)使用.toString(),即使你看不到它。 – Dee2000

+0

呃,不是真的。有帖子解釋了eval和Function之間的區別。順便說一下,23沒有'toString'方法來調用。如果你不信任我,試試'var x = 23; x.toString = function(){return「69」; };文件撰寫(X);'。現在用'var x = Object(23);'替換第一條語句,你會看到區別。 – ft1

+0

我喜歡它。我採用了這種方法:) – Dee2000

0

除非這是一些生病的實驗,否則不應該編寫看起來像這樣的Javascript代碼。這很糟糕;你需要重新考慮你的設計。我知道這不是你要找的,但它是正確的答案。

+0

這是真的。雖然我無法控制設計。 – Dee2000

0

事實是你已經有了一塊javscript表達的一個字符串,所以你要麼必須自己解析它或使用eval,除非你改變它通過這樣的方式來解析它給你:

function echoVar(a,b) { 
    var x = window[a]; 
    if (b) { 
     x = x[b]; 
    } 
    document.write(x); 
} 

而且,那麼你可以通過不同的像這樣:

var def = ["DEF"]; 
echoVar("def", 0); // def[0] 

你甚至可以使這一支持多種尺寸,如果你需要的。

function echoVar(a) { 
    var x = window[a]; 
    for (var i = 1; i < arguments.length; i++) { 
     x = x[arguments[i]]; 
    } 
    document.write(x); 
} 

var def = {myObject: {length: 3}} 
echoVar("def", "myObject", "length"); // def["myObject"]["length"] or def.myObject.length 

你可以看到它在這裏工作:http://jsfiddle.net/jfriend00/dANwq/

+0

可悲的是我不能控制調用格式。 – Dee2000

+0

然後,您必須自己解析它或使用eval() - 您的選擇。只要這不是最終用戶提供的字符串,我看不到只使用'eval()'的問題。 – jfriend00

+0

這就是我自己也得出的結論,無論是使用eval還是使用六行代碼膨脹它。我想我會來這裏,看看是否有一個我不知道的聰明解決方案。 – Dee2000

0

它會更簡單失去支架和用點分數表示該物品

function reval(s, O){ 
    s= String(s); 
    O= O || window; 
    var N= s.split("."); 
    while(O && N.length) O= O[N.shift()]; 
    return O || s; 
} 

window.def= ['definition']; 
alert(reval('def.0')) 

/* returned value: (String) 
definition 
*/ 
+0

只是稍微簡單一點,它只是表示我沒有結尾],而parseInt無論如何都忽略它。另外,我沒有控制調用格式,否則我會重新設計它,並且使它傳遞對象本身而不是字符串。 – Dee2000