2010-02-18 10 views
5

In Javascript, esiste un modo per creare una funzione da una stringa (ad esempio attraverso il nuovo costruttore Function) e ereditare l'ambito principale? Per esempio:Creazione di una funzione da una stringa che eredita l'ambito genitore

(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() 
})() 

Esiste un modo per fare whee.testy() anche alert "super yay"?

+2

C'è qualche motivo per cui questo è stato downvoted? – cletus

+1

Non penso sia possibile. – SLaks

+1

Penso che non dovresti volerlo fare. Davvero, questo potrebbe essere molto pericoloso. Qual è lo scopo di creare una funzione da una stringa? Cosa stai cercando di ottenere? –

risposta

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() 
})() 

Questo sembra funzionare per me, e nessuno dei dati eval'd da qualsiasi fonte non attendibile. È solo per essere usato per il codice minifying.

-1

Vuoi dire 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() 
})() 

Tuttavia ci sono due caratteristiche moralmente discutibili di JS qui. 1) eval è "male", e 2) il codice all'interno dell'eval può vedere le variabili all'esterno.

+0

'eval' è ** male **! Non usarlo! Non farlo! –

+0

Ed ecco una spiegazione migliore perché non usare eval: http://stackoverflow.com/questions/197769/when-is-javascripts-eval-not-evil/198031#198031 –

+0

Come ho detto: moralmente discutibile –

1

In realtà, combinando function e eval dovrebbe fare quello che vuoi:

// 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

Ma l'OP deve essere ** molto ** sicuro che la stringa non contenga codice dannoso Sono interessato al modo in cui alla stringa viene assegnato il suo valore –

+10

Sì, sì ... eval è il male e tutto il resto. A giudicare dal modo in cui OP ha creato l'anonimo funziona attorno al suo codice, non è il suo primo giorno a fare JS. – levik

+0

Sto solo usando eval/Function per comprimere meglio del codice, non è roba che viene inserita dall'utente, ma ho solo del codice dove ci sono molte funzioni con pochissimo codice all'interno, function (e) {var t = questo: return e (t)? [t]: []} e c'è una notevole quantità di byte che vengono usati con la funzione (e) {var t = this; return}. – antimatter15

-1

Non è necessario eval.

Devi concatenare il blah alla funzione di stringa, ma JavaScript si lamenterà che non c'è ";" appena prima della concatenazione è perché blah è solo un testo quando lo concatenate. Dovete fuggire due "\"" intorno al bla variabile al fine di far sembrare una stringa con testo in esso.

(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() 
})() 

Questo avviso 'super yay' due volte!

+0

Ma se avessi aggiornato il valore di "blah", whee.testy() avrebbe avvisato il valore sbagliato. – antimatter15

0

La ragione perché whee.testy non funziona è perché dichiarare una funzione utilizzando new Function("alert(blah)") crea la funzione di fuori della chiusura corrente. Dal momento che blah è definito all'interno del vostro chiusura, non si ha accesso ad esso, ed esso genera un errore indefinito.

Qui è un esempio di dimostrazione del concetto:

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

So perché non funzionerà, ma c'è un modo per farlo funzionare? – antimatter15

+0

@ antimatter15: No ... 'new Function (string)' definisce una funzione nell'ambito globale. Questo è di design. Usa invece le funzioni anonime. –

1

Questo dovrebbe dare ciò che si vuole ...

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

'fondamentalmente avvolge la vostra azione prevista all'interno di una funzione anonima, questo viene pienamente valutata in eval, ma non viene eseguito immediatamente, è avvolto in una funzione.

Qui puoi andare un po 'più lontano, ma senza sapere cosa vuoi ottenere è difficile da dire.

Problemi correlati