2012-06-15 67 views
6

有沒有辦法在調用eval()時指定全局使用哪個對象?將eval()與自定義全局一起使用

(我不問如何做全球的eva​​l()。)

這不是工作,但是這說明我想什麼:

var pseudoGlobal = {}; 
eval("x = 12", pseudoGlobal); 
pseudoGlobal.x; // 12 

的一點是,真正的全球性綁定不受代碼eval()'ed中的隱式變量聲明(即,沒有var關鍵字)的影響。

至於eval.call(pseudoGlobal, "x=12")eval.apply(pseudoGlobal, ["x=12"]),一些口譯員不會允許它。

+1

目的是在Javascript本身內創建一個獨立/受控/安全的執行環境。 – gawi

回答

3

你可以,當然,替代默認對象分配的屬性值,就像在

with (pseudoGlobal) eval("x=12") 

而不是創建一個屬性格式。如果在當前的執行上下文的棧中沒有找到屬性,它將在全局對象中創建。這裏的所有都是它的。 你可以嘗試一些奇怪的事情,也:

//global code 
var globalvars = {}; 
for (i in this) 
    globalvars[i] = null; 
with (pseudoGlobal) 
    eval("x=12") 
for (i in this) 
    if (!(i in globalvars)) 
{ 
    pseudoGlobal[i] = this[i]; 
    delete this[i]; 
} 

如果你關心全局綁定,請嘗試:

var globalvars = {}; 
for (i in this) 
    globalvars[i] = this[i]; 
with (globalvars) 
    eval("x=12") 

這樣的綁定將在globalvars改變。請注意,該淺拷貝將防止只有一個級別的變化發生變化。

+0

關於你的第二個代碼塊,這並不妨礙腳本改變實際全局對象中的綁定。 – gawi

+0

我把你的問題的面值,但仍然不是全部丟失...更新了答案 –

+0

如果我做'eval(''使用strict';'+ code)',而它約束的代碼可以是eval ()'ed,這可以防止在全局範圍內創建額外的綁定。這給我們留下了level-2 +結合的可能突變。 – gawi

1

沒有內置的方法來做到這一點。

有兩種解決方案,浮現在腦海中:在eval編代碼

  • 前綴的所有任務。即,而不是x = 12,你將不得不做一些像o.x = 12
  • 編寫您自己的JavaScript解釋器,將沙箱的腳本和返回一個對象與所有分配的變量。
+0

太糟糕了,我們無法用Javascript創建我們自己的執行環境。 Javascript必須存在一些很好的理由來防止這種情況。我覺得它比我想象的要複雜一點(原型鏈?構造函數?本地函數?)。 – gawi

相關問題