2010-02-18 41 views
5

在Javascript中,有沒有一種方法可以從一個字符串(例如通過新的Function()構造函數)創建一個函數,並讓它繼承父範圍?例如:從繼承父範圍的字符串創建函數

(function(){ 
    function yay(){ 
    } 
    var blah = "super yay" 
    yay.prototype.testy = new Function("alert(blah)") 
    yay.prototype.hello = function(){alert(blah)} 
    whee = new yay(); 
    whee.hello() 
    whee.testy() 
})() 

有沒有什麼辦法讓whee.testy()也提醒「超級耶」?

+2

這是否有一些原因downvoted? – cletus 2010-02-18 03:00:39

+1

我不認爲這是可能的。 – SLaks 2010-02-18 03:04:48

+1

我認爲你不應該這樣做。真的,這可能是非常危險的。從字符串創建函數的目的是什麼?你想達到什麼目的? – 2010-02-18 15:06:20

回答

1
(function(){ 
    function yay(){ 
    } 
    var blah = "super yay" 
    yay.prototype.testy = eval("(function(){alert(blah)})")//new Function("alert(blah)") 
    yay.prototype.hello = function(){alert(blah)} 
    whee = new yay(); 
    whee.hello() 
    whee.testy() 
})() 

這似乎爲我工作,並沒有eval'd數據是來自不受信任的來源。它只是用於縮小代碼。

-1

您的意思是eval?

(function(){ 
    function yay(){ 
    } 
    var blah = "super yay" 
    yay.prototype.testy = new Function(eval("alert(blah)")) // <--------------- 
    yay.prototype.hello = function(){alert(blah)} 
    whee = new yay(); 
    whee.hello() 
    whee.testy() 
})() 

然而,JS在這裏有兩個道德上令人反感的特徵。 1)eval是「evil」,並且2)eval中的代碼可以看到外部的變量。

+0

'eval'是**惡**!不要使用它!別! – 2010-02-18 03:23:54

+0

這裏有一個更好的解釋,爲什麼不使用eval:http://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil/198031#198031 – 2010-02-18 03:31:12

+0

就像我說的:morally令人反感 – 2010-02-18 04:25:35

1

事實上,結合functioneval應該做你想要什麼:

// blah exists inside the 'hello' function 
yay.prototype.hello = function(){ alert(blah) } 
// blah also exists inside the 'testy' function, and 
// is therefore accessible to eval(). 
yay.prototype.testy = function(){ eval('alert(blah)') } 
+0

但是OP必須非常確定該字符串不包含任何惡意代碼。我對字符串賦值的方式很感興趣 – 2010-02-18 13:24:51

+10

是的,是的...... eval是邪惡的,所有這一切都是通過OP創建匿名的方式來判斷的圍繞他的代碼運行,這不是他第一天做JS的時間。 – levik 2010-02-18 20:58:17

+0

我只是使用eval/Function來更好地壓縮一些代碼,它不是用戶輸入的東西,但我只是有一些代碼,其中有很多函數,只有很少的代碼,function(e){var t = this; return e(t)?[t]:[]}並且有大量的字節被函數(e){var t = this; return}用完。 – antimatter15 2010-02-19 21:02:15

-1

你不需要評估。

您必須將blah連接到字符串函數,但JavaScript會抱怨沒有「;」就在連接之前,這是因爲當連接它時,blah只是一些文本。你必須逃脫兩個「\」」周圍的變量等等,以便使它看起來像在它的文本字符串。

(function(){ 
    function yay(){ 
    } 
var blah = "super yay" 

yay.prototype.testy = new Function("alert(\""+blah+"\")") 
yay.prototype.hello = function(){alert(blah)} 
whee = new yay(); 
whee.hello() 
whee.testy() 
})() 

這將提醒‘超級耶’的兩倍!

+0

但是如果我更新了「blah」的值,那麼whee.testy()會提醒錯誤的值。 – antimatter15 2010-03-05 20:29:40

0

原因爲什麼whee.testy不工作是因爲使用聲明一個new Function("alert(blah)")功能創建當前封閉外的函數。由於blah是你的閉包內定義的,你沒有訪問它,它拋出一個未定義的錯誤。

這裏是概念驗證示例:

var blah = "global (window) scope"; 

(function(){ 
    function yay(){ 
    } 
    var blah = "closure scope"; 

    yay.prototype.testy = new Function("alert(blah)"); 
    yay.prototype.hello = function(){ alert(blah); } 
    whee = new yay(); 
    whee.hello(); 
    whee.testy(); 
})(); 
+0

我知道它爲什麼不起作用,但有沒有辦法讓它工作? – antimatter15 2010-03-05 20:30:01

+0

@ antimatter15:No ...'new Function(string)'在全局範圍內定義一個函數。這是設計。改用匿名函數。 – 2010-03-05 22:08:43

1

這應該給你想要的東西......

var inputAction = "alert(blah)"; 
yay.prototype.testy = eval("(function(){ " + inputAction + "; })")

它基本上包裝了一個匿名函數內部預期的作用,這得到充分的評估EVAL,但不運行的時候了,它被包裝成一個函數。

你可以在這裏走得更遠,但不知道你想完成什麼,這很難說。