Perché usare la funzione JavaScript eval è una cattiva idea?


534

La funzione eval è un modo semplice e potente per generare dinamicamente codice, quindi quali sono le avvertenze?


92
Don't be eval () di Simon Willison - 24ways.org/2005/dont-be-eval
Brian Singh,

5
Come indicato in moduscreate.com/javascript-performance-tips-tricks - (new Function (str)) () è più performante di eval (str). Solo i miei 2 centesimi :)
Grgur

3
apparentemente nuovo fcuntion (a) è il 67% più lento di eval (a) su Chrome
che cos'è il sonno

per me le nuove funzioni (a) sono più recenti dell'80% più recenti su Chrome su osx
john Smith

3
Ho aggiunto una funzione statica, solo per confrontare le prestazioni. jsperf.com/eval-vs-new-function/2
Nepoxx,

Risposte:


386
  1. L'uso improprio di eval apre il codice per gli attacchi di iniezione

  2. Il debug può essere più impegnativo (nessun numero di riga, ecc.)

  3. il codice eval'd viene eseguito più lentamente (nessuna possibilità di compilare / memorizzare nella cache il codice eval'd)

Modifica: Come sottolinea @Jeff Walden nei commenti, oggi la # 3 è meno vera di quanto non fosse nel 2008. Tuttavia, mentre alcune operazioni di cache degli script compilati possono accadere, ciò sarà limitato solo agli script che verranno valutati ripetuti senza alcuna modifica. Uno scenario più probabile è che stai valutando script che hanno subito lievi modifiche ogni volta e che pertanto non possono essere memorizzati nella cache. Diciamo solo che ALCUNI codici valutati vengono eseguiti più lentamente.


2
@JeffWalden, ottimo commento. Ho aggiornato il mio post anche se mi rendo conto che è passato un anno da quando hai pubblicato. Xnzo72, se avessi qualificato un po 'il tuo commento (come ha fatto Jeff), allora potrei essere d'accordo con te. Jeff ha sottolineato la chiave: "l'eval della stessa stringa più volte può evitare di analizzare le spese generali". Così com'è, ti sbagli di grosso; # 3 vale per molti scenari.
Prestaul,

7
@Prestaul: Dal momento che il presunto utente malintenzionato può semplicemente utilizzare qualsiasi strumento di sviluppo per modificare il JavaScript nel client, perché dici che Eval () apre il tuo codice agli attacchi di iniezione? Non è già aperto? (Sto parlando del client JavaScript ovviamente)
Eduardo Molteni,

60
@EduardoMolteni, non ci interessa (e in effetti non possiamo impedire) agli utenti di eseguire js nel proprio browser. Gli attacchi che stiamo cercando di evitare sono quando i valori forniti dall'utente vengono salvati, quindi inseriti in javascript e valutati. Ad esempio, potrei impostare il mio nome utente su: badHackerGuy'); doMaliciousThings();e se prendi il mio nome utente, lo concatichi in alcuni script e lo valuti nei browser di altre persone, allora posso eseguire qualsiasi javascript che desidero sui loro computer (ad esempio forzarli a fare +1 sui miei post, pubblica i loro dati sul mio server, ecc.)
Prestaul,

3
In generale, il numero 1 è vero per parecchie, se non la maggior parte delle chiamate di funzione. eval () non dovrebbe essere individuato ed evitato da programmatori esperti, solo perché i programmatori inesperti lo abusano. Tuttavia, i programmatori esperti hanno spesso un'architettura migliore nel loro codice e raramente sarà richiesto o addirittura pensato a causa di questa architettura migliore.
frodeborli,

4
@TamilVendhan Sicuro che puoi mettere punti di interruzione. Puoi accedere al file virtuale creato da Chrome per il tuo codice valutato aggiungendo l' debugger;istruzione al codice sorgente. Ciò interromperà l'esecuzione del programma su quella linea. Quindi, è possibile aggiungere punti di interruzione di debug come se fosse solo un altro file JS.
Sid

346

eval non è sempre malvagio. Ci sono momenti in cui è perfettamente appropriato.

Tuttavia, eval è attualmente e storicamente massicciamente utilizzato da persone che non sanno cosa stanno facendo. Ciò include le persone che scrivono tutorial JavaScript, sfortunatamente, e in alcuni casi ciò può effettivamente avere conseguenze sulla sicurezza o, più spesso, semplici bug. Quindi più possiamo fare per gettare un punto interrogativo su eval, meglio è. Ogni volta che usi eval devi controllare la sanità mentale di ciò che stai facendo, perché è probabile che tu possa farlo in un modo migliore, più sicuro e più pulito.

Per fare un esempio fin troppo tipico, per impostare il colore di un elemento con un id memorizzato nella variabile 'potato':

eval('document.' + potato + '.style.color = "red"');

Se gli autori del tipo di codice sopra riportato avessero avuto un'idea delle basi di come funzionano gli oggetti JavaScript, avrebbero capito che è possibile usare parentesi quadre anziché letterali dot-points, ovviando alla necessità di eval:

document[potato].style.color = 'red';

... che è molto più facile da leggere e meno potenzialmente buggy.

(Ma poi, qualcuno che / realmente / sapeva cosa stavano facendo avrebbe detto:

document.getElementById(potato).style.color = 'red';

che è più affidabile del vecchio trucco ingannevole di accedere agli elementi DOM direttamente dall'oggetto documento.)


82
Hmm, immagino di essere stato fortunato quando stavo imparando JavaScript per la prima volta. Ho sempre usato "document.getElementById" per accedere al DOM; ironia della sorte, l'ho fatto solo in quel momento perché non avevo idea di come funzionassero gli oggetti in JavaScript ;-)
Mike Spross

5
essere d'accordo. A volte eval è ok, ad esempio per le risposte JSON dai servizi
web

40
@schoetbi: non dovresti usare JSON.parse()invece che eval()per JSON?
nyuszika7h

4
@bobince code.google.com/p/json-sans-eval funziona su tutti i browser, così github.com/douglascrockford/JSON-js . Json2.js di Doug Crockford usa eval internamente, ma con i controlli. Inoltre, è compatibile in avanti con il supporto browser integrato per JSON.
Martijn,

8
@bobince C'è qualcosa chiamato funzionalità di rilevamento e polyfill per gestire le librerie JSON mancanti e altre cose (guarda modernizr.com )
MauganRa

37

Credo che sia perché può eseguire qualsiasi funzione JavaScript da una stringa. Usarlo rende più facile per le persone iniettare codice canaglia nell'applicazione.


5
Qual è l'alternativa allora?
moderns

5
In realtà l'alternativa è semplicemente scrivere codice che non lo richiede. Crockford approfondisce questo aspetto e, se è necessario utilizzarlo, dice praticamente che è un difetto di progettazione del programma e deve essere rielaborato. In verità, sono d'accordo anche con lui. JS per tutti i suoi difetti è davvero flessibile e consente a molto spazio di renderlo flessibile.
kemiller2002,

3
Non è vero, la maggior parte dei framework ha un metodo per analizzare JSON e, se non si utilizza un framework, è possibile utilizzare JSON.parse (). La maggior parte dei browser lo supporta e, se hai davvero un pizzico, potresti scrivere un parser per JSON abbastanza facilmente.
kemiller2002,

6
Non compro questo argomento, perché è già facile iniettare codice canaglia in un'applicazione Javascript. Abbiamo console per browser, estensioni di script, ecc ... Ogni singolo pezzo di codice inviato al client è facoltativo per l'esecuzione del client.
user2867288

6
Il punto è che è più facile per me inserire il codice nel tuo browser. Supponiamo che tu stia utilizzando eval su una stringa di query. Se ti induco a fare clic su un collegamento che va a quel sito con la mia stringa di query allegata, ora ho eseguito il mio codice sulla tua macchina con il pieno consenso del browser. Voglio registrare tutto ciò che digiti su quel sito e inviarlo a me? Fatto e nessun modo per fermarmi perché quando eval viene eseguito, il browser gli conferisce la massima autorità.
kemiller2002,

27

Mi vengono in mente due punti:

  1. Sicurezza (ma fino a quando si genera la stringa da valutare da soli, questo potrebbe non essere un problema)

  2. Prestazioni: fino a quando il codice da eseguire non è sconosciuto, non può essere ottimizzato. (su javascript e performance, sicuramente la presentazione di Steve Yegge )


9
Perché la sicurezza è un problema se il client potrebbe comunque fare con il nostro codice tutto ciò che desidera? Greasemonkey?
Paul Brewczynski

2
@PaulBrewczynski, il problema di sicurezza appare quando l'utente A salva la sua parte di codice da utilizzare evale poi quel frammento di codice viene eseguito sul browser B dell'utente
Felipe Pereira,

21

Passare l'input dell'utente a eval () è un rischio per la sicurezza, ma anche ogni invocazione di eval () crea una nuova istanza dell'interprete JavaScript. Questo può essere un porco di risorse.


27
Negli ultimi 3 anni da quando ho risposto a questo, la mia comprensione di ciò che accade è, diciamo, approfondita. Ciò che effettivamente accade è che viene creato un nuovo contesto di esecuzione. Vedi dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts
Andrew Hedges,

20

In genere è solo un problema se si passa l'input dell'utente eval.


16

Principalmente, è molto più difficile da mantenere e eseguire il debug. È come a goto. Puoi usarlo, ma rende più difficile trovare problemi e più difficile per le persone che potrebbero aver bisogno di apportare modifiche in seguito.


Eval può essere utilizzato per sostituire le funzioni di metaprogrammazione mancanti, come i modelli. Mi piace il generatore compatto molto più che un elenco infinito di funzioni su funzioni.
weaknespase,

Finché la stringa non proviene dall'utente o è limitata al browser, è possibile. JavaScript ha un sacco di potere di metaprogrammazione usando cose come cambiare prototipi, obj [membro], Proxy, json.parse, finestra, funzioni del decoratore (avverbi) dove newf = decoratore (vecchio), funzione di ordine superiore come Array.prototype.map (f) , passando argomenti ad altre funzioni, argomenti di parole chiave tramite {}. Puoi dirmi un caso d'uso in cui non puoi fare queste invece di valutare?
aoeu256,

13

Una cosa da tenere a mente è che spesso puoi usare eval () per eseguire il codice in un ambiente altrimenti limitato - i siti di social network che bloccano specifiche funzioni JavaScript possono a volte essere imbrogliati rompendoli in un blocco eval -

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

Quindi, se stai cercando di eseguire un codice JavaScript in cui altrimenti non potrebbe essere consentito ( Myspace , ti sto guardando ...) allora eval () può essere un trucco utile.

Tuttavia, per tutte le ragioni sopra menzionate, non dovresti usarlo per il tuo codice, dove hai il controllo completo - non è solo necessario, e meglio relegato nello scaffale degli "hacker JavaScript complicati".


1
Basta aggiornare il codice sopra ... - ehi! - deve essere tra virgolette perché è una stringa. eval ('al' + 'er' + 't (' + '"ciao lì!"' + ')');
Mahesh,

2
[]["con"+"struc"+"tor"]["con"+"struc"+"tor"]('al' + 'er' + 't(\'' + 'hi there!' + '\')')()
Konrad Borowski,

4
Sì, c'erano siti di social network che limitavano alert () ma permettevano eval () ?!
joshden,

12

A meno che non lasci a eval () un contenuto dinamico (tramite cgi o input), è sicuro e solido come tutti gli altri JavaScript nella tua pagina.


Anche se questo è vero - se i tuoi contenuti non sono dinamici, quale motivo c'è per usare eval? Potresti semplicemente mettere il codice in una funzione e chiamarlo, invece!
Periata Breatta,

Ad esempio, per analizzare il valore di ritorno (tipo JSON, stringhe definite dal server, ecc.) Proveniente dalla chiamata Ajax.
Il

2
Oh, capisco. Chiamerei quelli dinamici perché il cliente non sa in anticipo cosa sono, ma capisco cosa intendi ora.
Periata Breatta,

7

Insieme al resto delle risposte, non credo che le dichiarazioni di valutazione possano avere una minimizzazione avanzata.


6

È un possibile rischio per la sicurezza, ha un diverso ambito di esecuzione ed è abbastanza inefficiente, in quanto crea un ambiente di scripting completamente nuovo per l'esecuzione del codice. Vedi qui per qualche informazione in più: eval .

È abbastanza utile, tuttavia, e usato con moderazione può aggiungere molte buone funzionalità.


5

A meno che non si sia sicuri al 100% che il codice in fase di valutazione provenga da una fonte attendibile (di solito la propria applicazione), si tratta di un modo infallibile di esporre il sistema a un attacco di scripting tra siti.


1
Solo se la tua sicurezza lato server fa schifo. La sicurezza sul lato client non ha senso.
doubleOrt

5

So che questa discussione è vecchia, ma mi piace molto questo approccio di Google e volevo condividere questo sentimento con gli altri;)

L'altra cosa è che meglio ottieni e più cerchi di capire e infine non credi che qualcosa sia buono o cattivo solo perché qualcuno l'ha detto :) Questo è un video molto stimolante che mi ha aiutato a pensare di più da solo :) LE BUONE PRATICHE sono buone, ma non usarle senza pensarci :)


1
Sì. Ho trovato, finora almeno in Chrome, un caso d'uso che sembra essere più efficiente. Esegui un RAF che eleva una stringa in una determinata variabile ogni iterazione. Usa un setInterval per impostare solo cose orientate graficamente come impostare trasformazioni, ecc. In quella stringa. Ho provato molti altri approcci come il looping delle funzioni in un array o l'utilizzo di una variabile per impostare solo trasformazioni per elementi che sono stati modificati, ma finora questo sembra essere il più efficiente. Quando si tratta di animazione, il test di banco più vero sono i tuoi occhi.
jdmayfield,

5

Non è necessariamente così male purché tu sappia in quale contesto lo stai usando.

Se l'applicazione sta utilizzando eval()per creare un oggetto da alcuni JSON che è tornato da un XMLHttpRequest al tuo sito, creato dal tuo codice lato server attendibile, probabilmente non è un problema.

Il codice JavaScript sul lato client non attendibile non può fare altrettanto. A condizione che la cosa su cui stai eseguendo eval()provenga da una fonte ragionevole, stai bene.


3
L'uso di eval non è più lento del semplice analisi di JSON?
Brendan Long,

@Qix: eseguire quel test sul mio browser (Chrome 53) mostra eval come un po 'più veloce dell'analisi .
Periata Breatta,

@PeriataBreatta Huh, strano. Mi chiedo perché. Al momento ho commentato che non era il caso. Tuttavia, non è raro che Chrome ottenga strani miglioramenti delle prestazioni in determinate aree del runtime da una versione all'altra.
Qix - MONICA È STATA MISTREATA il

Un po 'di vecchio filo qui, ma da quello che ho letto, senza pretendere di averlo rintracciato da solo, JSON.parse in effetti è che il suo input sia nella fase finale. Quindi, dal punto di vista dell'efficienza, richiede più lavoro / tempo. Ma per quanto riguarda la sicurezza, perché non analizzare? eval è uno strumento fantastico. Usalo per cose che non hanno altro modo. Per passare le funzioni tramite JSON, esiste un modo per farlo senza eval. Quel secondo parametro in JSON.stringify ti consente di eseguire un callback che puoi controllare tramite typeof se è una funzione. Quindi ottenere la funzione .toString (). Ci sono alcuni buoni articoli su questo se cerchi.
jdmayfield,


4

Se si desidera che l'utente inserisca alcune funzioni logiche e valuti AND e OR, la funzione di valutazione JavaScript è perfetta. Posso accettare due stringhe e eval(uate) string1 === string2, ecc.


Puoi anche usare Function () {}, ma fai attenzione quando li usi sul server a meno che tu non voglia che gli utenti prendano il controllo del tuo server hahahah.
aoeu256,

3

Se noti l'uso di eval () nel tuo codice, ricorda che il mantra "eval () è malvagio".

Questa funzione accetta una stringa arbitraria e la esegue come codice JavaScript. Quando il codice in questione è noto in anticipo (non determinato in fase di esecuzione), non c'è motivo di usare eval (). Se il codice viene generato dinamicamente in fase di esecuzione, spesso c'è un modo migliore per raggiungere l'obiettivo senza eval (). Ad esempio, usare la notazione tra parentesi quadre per accedere alle proprietà dinamiche è migliore e più semplice:

// antipattern
var property = "name";
alert(eval("obj." + property));

// preferred
var property = "name";
alert(obj[property]);

L'uso eval()ha anche implicazioni per la sicurezza, perché potresti eseguire codice (ad esempio proveniente dalla rete) che è stato manomesso. Questo è un antipattern comune quando si ha a che fare con una risposta JSON da una richiesta Ajax. In questi casi è meglio usare i metodi integrati dei browser per analizzare la risposta JSON per assicurarsi che sia sicura e valida. Per i browser che non supportanoJSON.parse() nativamente, è possibile utilizzare una libreria di JSON.org.

È anche importante ricordare che passare stringhe a setInterval(), setTimeout()e il Function()costruttore è, per la maggior parte, simile all'uso eval()e quindi dovrebbe essere evitato.

Dietro le quinte, JavaScript deve ancora valutare ed eseguire la stringa che passi come codice di programmazione:

// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);

// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);

L'uso del nuovo costruttore Function () è simile a eval () e dovrebbe essere affrontato con cura. Potrebbe essere un costrutto potente ma è spesso usato in modo improprio. Se devi assolutamente usareeval() , puoi considerare di usare invece la nuova funzione ().

Vi è un piccolo vantaggio potenziale perché il codice valutato nella nuova funzione () verrà eseguito nell'ambito di una funzione locale, quindi qualsiasi variabile definita con var nel codice che viene valutato non diventerà automaticamente globale.

Un altro modo per prevenire i globi automatici è avvolgere la eval()chiamata in una funzione immediata.


Puoi suggerire come potrei valutare un nome di variabile dinamica locale-funzione senza eval? Le funzioni eval (e simili) sono le ultime risorse nella maggior parte delle lingue che le contengono, ma a volte è necessario. Nel caso di ottenere il nome di una variabile dinamica, c'è qualche soluzione più sicura? In ogni caso, javascript stesso non è per la vera sicurezza (il lato server è ovviamente la difesa principale). Se sei interessato, ecco il mio caso d'uso di eval, che mi piacerebbe cambiare: stackoverflow.com/a/48294208
Regular Joe

2

Oltre ai possibili problemi di sicurezza se si esegue il codice inviato dall'utente, la maggior parte delle volte esiste un modo migliore che non comporta il riesame del codice ogni volta che viene eseguito. Le funzioni anonime o le proprietà degli oggetti possono sostituire la maggior parte degli usi di eval e sono molto più sicure e veloci.


2

Questo potrebbe diventare più un problema poiché la prossima generazione di browser esce con un po 'di sapore di un compilatore JavaScript. Il codice eseguito tramite Eval potrebbe non funzionare così come il resto del tuo JavaScript rispetto a questi browser più recenti. Qualcuno dovrebbe fare un po 'di profilazione.


2

Questo è uno dei buoni articoli che parlano di eval e di come non sia un male: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

Non sto dicendo che dovresti esaurirti e iniziare a usare eval () ovunque. In effetti, ci sono pochissimi casi d'uso per eseguire eval (). Ci sono sicuramente dubbi sulla chiarezza del codice, sulla debugabilità e certamente sulle prestazioni che non devono essere trascurate. Ma non dovresti aver paura di usarlo quando hai un caso in cui eval () ha un senso. Prova a non usarlo prima, ma non lasciare che nessuno ti spaventi a pensare che il tuo codice sia più fragile o meno sicuro quando eval () viene usato in modo appropriato.


2

eval () è molto potente e può essere utilizzato per eseguire un'istruzione JS o valutare un'espressione. Ma la domanda non riguarda gli usi di eval () ma diciamo solo in che modo la stringa che si esegue con eval () è influenzata da una parte malvagia. Alla fine eseguirai codice dannoso. Con il potere derivano grandi responsabilità. Quindi usalo saggiamente se lo stai usando. Questo non è molto legato alla funzione eval () ma questo articolo contiene informazioni piuttosto buone: http://blogs.popart.com/2009/07/javascript-injection-attacks/ Se stai cercando le basi di eval () guarda qui: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval


2

Il motore JavaScript ha una serie di ottimizzazioni delle prestazioni che esegue durante la fase di compilazione. Alcuni di questi si riducono alla capacità di analizzare staticamente essenzialmente il codice man mano che si allenta e predeterminare dove si trovano tutte le dichiarazioni di variabili e funzioni, in modo che ci voglia meno sforzo per risolvere gli identificatori durante l'esecuzione.

Ma se il motore trova una valutazione (..) nel codice, essenzialmente deve presumere che tutta la sua consapevolezza della posizione dell'identificatore potrebbe essere non valida, perché non può sapere al momento giusto quale codice si può passare a valutazione (..) per modificare l'ambito lessicale o il contenuto dell'oggetto a cui è possibile passare per creare un nuovo ambito lessicale da consultare.

In altre parole, in senso pessimistico, la maggior parte di quelle ottimizzazioni che avrebbe fatto sono inutili se è presente eval (..), quindi semplicemente non esegue affatto le ottimizzazioni.

Questo spiega tutto.

Riferimento:

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance


Nessun motore JavaScript non è in grado di trovare e valutare il codice con una garanzia del 100%. Pertanto, deve essere pronto per questo in qualsiasi momento.
Jack Giffin,

2

Non è sempre una cattiva idea. Prendiamo ad esempio la generazione del codice. Di recente ho scritto una libreria chiamata Hyperbars che colma il divario tra virtual-dom e manubrio . Lo fa analizzando un modello di manubrio e convertendolo in iperscript che viene successivamente utilizzato da virtual-dom. L'iperscript viene generato prima come stringa e prima di restituirlo, eval()per trasformarlo in codice eseguibile. Ho trovato eval()in questa particolare situazione l'esatto contrario del male.

Fondamentalmente da

<div>
    {{#each names}}
        <span>{{this}}</span>
    {{/each}}
</div>

A questo

(function (state) {
    var Runtime = Hyperbars.Runtime;
    var context = state;
    return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
        return [h('span', {}, [options['@index'], context])]
    })])
}.bind({}))

Le prestazioni di eval()non sono un problema in una situazione come questa perché è necessario interpretare la stringa generata una sola volta e riutilizzare più volte l'output eseguibile.

Puoi vedere come è stata raggiunta la generazione del codice se sei curioso qui .


2

Andrei fino al punto di dire che non importa davvero se lo usi eval() javascript che viene eseguito nei browser. * (Avvertenza)

Tutti i browser moderni hanno una console per sviluppatori in cui è possibile eseguire javascript arbitrari in ogni caso e qualsiasi sviluppatore semi-intelligente può guardare la tua fonte JS e mettere tutti i bit di cui ha bisogno nella console di sviluppo per fare ciò che desidera.

* Fintanto che gli endpoint del server hanno la corretta convalida e sanificazione dei valori forniti dall'utente, non dovrebbe importare ciò che viene analizzato e valutato nel javascript sul lato client.

Se dovessi chiederti se è adatto da usare eval()in PHP, la risposta è NO , a meno che tu non autorizzi tutti i valori che possono essere passati alla tua dichiarazione di valutazione.


non c'è solo una console di sviluppo, puoi anche digitare javascript: codice nella barra dell'URL per creare la tua console di sviluppo sulla pagina se non ce n'è, come nel caso dei vecchi browser IE e dispositivi mobili.
Dmitry,

1

Non tenterò di confutare nulla di ciò che è stato detto finora, ma offrirò questo uso di eval () che (per quanto ne so) non può essere fatto in nessun altro modo. Probabilmente ci sono altri modi per codificare questo, e probabilmente modi per ottimizzarlo, ma questo è fatto a mano e senza campane e fischietti per chiarezza per illustrare un uso di eval che in realtà non ha altre alternative. Cioè: nomi di oggetti dinamici (o più precisamente) creati in modo programmatico (in contrapposizione ai valori).

//Place this in a common/global JS lib:
var NS = function(namespace){
    var namespaceParts = String(namespace).split(".");
    var namespaceToTest = "";
    for(var i = 0; i < namespaceParts.length; i++){
        if(i === 0){
            namespaceToTest = namespaceParts[i];
        }
        else{
            namespaceToTest = namespaceToTest + "." + namespaceParts[i];
        }

        if(eval('typeof ' + namespaceToTest) === "undefined"){
            eval(namespaceToTest + ' = {}');
        }
    }
    return eval(namespace);
}


//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
  //Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
    //Code goes here
    //this.MyOtherMethod("foo"));  // => "foo"
    return true;
}


//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);

EDIT: a proposito, non suggerirei (per tutti i motivi di sicurezza finora indicati) di basare i nomi degli oggetti sull'input dell'utente. Non riesco a immaginare nessuna buona ragione per cui vorresti farlo. Tuttavia, ho pensato di sottolineare che non sarebbe stata una buona idea :)


3
questo può essere fatto con namespaceToTest[namespaceParts[i]], non c'è bisogno di eval qui, quindi if(typeof namespaceToTest[namespaceParts[i]] === 'undefined') { namespaceToTest[namespaceParts[i]] = {};l'unica differenza perelse namespaceToTest = namespaceToTest[namespaceParts[i]];
user2144406

1

Raccolta dei rifiuti

La garbage collection del browser non ha idea se il codice che viene valutato può essere rimosso dalla memoria, quindi lo mantiene solo fino a quando la pagina viene ricaricata. Non male se i tuoi utenti sono solo sulla tua pagina a breve, ma può essere un problema per webapp.

Ecco uno script per dimostrare il problema

https://jsfiddle.net/CynderRnAsh/qux1osnw/

document.getElementById("evalLeak").onclick = (e) => {
  for(let x = 0; x < 100; x++) {
    eval(x.toString());
  }
};

Qualcosa di semplice come il codice sopra fa sì che una piccola quantità di memoria venga archiviata fino alla morte dell'app. Questo è peggio quando la sceneggiatura valutata è una funzione gigante e viene chiamata a intervalli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.