Computer finestre Internet

Sicurezza JavaScript o come scrivere codice JS sicuro. Strumenti di controllo della versione

ALEXANDER MAYOROV, programmatore, 11 anni di esperienza nella programmazione, sette dei quali dedicati allo sviluppo per dispositivi mobili

Analisi del tipo statico in JavaScript
Provando l'analizzatore di flusso di Facebook

Facebook ha introdotto un nuovo progetto open source Flow: un analizzatore di codice statico per JavaScript. Lo scopo principale dello sviluppo dell'analizzatore è semplificare la ricerca degli errori.

Inoltre, Flow fornisce un'estensione sintattica JavaScript in stile TypeScript per specificare in modo esplicito i tipi. Molte delle nuove funzionalità introdotte nella specifica ECMAScript 6 sono supportate.

Il tema della digitazione nei linguaggi di programmazione è spesso toccato. Questo è l'argomento degli holivar e determina i tratti positivi o negativi di una particolare lingua. Ultimamente si è parlato molto della digitazione in JavaScript. A qualcuno piace così com'è. Le persone che hanno familiarità con altri linguaggi di programmazione, specialmente quelli con una forte tipizzazione esplicita, considerano questo approccio una "granata nelle mani di una scimmia". Sappiamo tutti che JavaScript è un linguaggio digitato in modo flessibile e dinamico. I guru dello sviluppo front-end hanno imparato a usarlo a proprio vantaggio, ma a volte il codice è troppo pesante da capire. Coloro che sono appena entrati nel mondo della programmazione JavaScript sono perplessi dalla magia che fa l'interprete e spesso colgono errori di punto in bianco. Ma prima, esaminiamo un po' la digitazione in generale. Com'è?

Digitazione nei linguaggi di programmazione

Digitando, i linguaggi di programmazione sono divisi in due grandi campi: digitati e non digitati. Ad esempio, le lingue digitate includono linguaggi come C, Python, PHP, Lua, JavaScript. Esempi di linguaggi non tipizzati: assembler, Forth, Brainfuck. Sì Sì esatto. JavaScript, come molti altri linguaggi interpretati, viene digitato. Pertanto, in nessun caso dire che non è digitato. Soprattutto nei colloqui di lavoro.

A loro volta, le lingue digitate sono suddivise in diverse categorie sovrapposte:

  • Digitato staticamente o dinamicamente.
  • Digitazione forte o vaga.
  • Digitato in modo esplicito o implicito.

Linguaggi tipizzati staticamente

Con la tipizzazione statica, i tipi finali di variabili e funzioni vengono impostati in fase di compilazione. Il compilatore corregge gli errori di mancata corrispondenza del tipo anche prima dell'avvio del programma. Esempi di linguaggi: C, Java, C#.

Linguaggi digitati dinamicamente

Nella digitazione dinamica, tutti i tipi vengono rilevati in fase di esecuzione. E se commetti un errore, lo saprai solo quando esegui il programma. Pertanto, quando si digita dinamicamente, è molto importante prestare particolare attenzione al controllo e alla cattura degli errori. Esempi di linguaggi: JavaScript, PHP, Python, Ruby.

Digitazione forte (forte)

I linguaggi fortemente tipizzati non consentono di mescolare tipi diversi nelle espressioni e non eseguiranno conversioni implicite automatiche. Ad esempio, non è possibile sottrarre un numero o qualsiasi altro tipo diverso da una stringa da una stringa. Esempi di linguaggi: Java, Python, Haskell, Lisp.

Digitazione lassista (debole)

Le lingue digitate liberamente eseguono automaticamente molte conversioni implicite. Lo fanno anche se possono verificarsi perdita di precisione o conversione, in modo ambiguo. Esempi di linguaggi: PHP, JavaScript, Visual Basic.

Digitazione esplicita

Nei linguaggi tipizzati in modo esplicito, il tipo di nuove variabili/funzioni e argomenti deve essere specificato in modo esplicito. Esempi di linguaggi: C++, D, C#.

Digitazione implicita

Nei linguaggi con tipizzazione implicita, il compito di specificare i tipi viene trasferito al compilatore/interprete. Esempi di linguaggi: JavaScript, PHP, Lua. In tali linguaggi, di norma, gli oggetti hanno metodi speciali che vengono chiamati al casting su un tipo. Ad esempio, PHP ha un metodo _toString () e JavaScript ha un metodo con lo stesso nome, ma senza un carattere di sottolineatura, - toString (). Questi metodi vengono chiamati quando viene eseguito il cast di un oggetto su un tipo stringa. A volte tali metodi sono chiamati magici (qualsiasi processo implicito è sempre magico).

È importante notare che tutte queste categorie si sovrappongono. Sulla base di queste categorie, vediamo che JavaScript è digitato in modo dinamico in modo implicito. E se parliamo in modo esagerato, allora la natura del linguaggio può essere descritta come segue: in ogni situazione incomprensibile, porta tutto ai primitivi, principalmente a una linea. Sebbene in realtà sia tutto un po' più complicato, non entreremo nei dettagli ora.

"Perché abbiamo bisogno di digitare?" - potresti chiedere. JavaScript ha vissuto bene senza di esso per 20 anni. La risposta è semplice: JavaScript non è mai stato utilizzato per risolvere problemi complessi a livello aziendale. Ora questo linguaggio è andato oltre il browser ed è entrato nel territorio del backend. Quando si scrive un'applicazione di grandi dimensioni, diventa difficile rilevare gli errori spesso associati al casting.

Componenti aggiuntivi JavaScript

Poiché JavaScript viene eseguito sul lato client (nei browser), una delle opzioni per risolvere il problema è creare un linguaggio, un dialetto che verrà compilato in JS. Agisce come assemblatore.

Sono emersi linguaggi come TypeScript, Dart, AtScript che aggiungono una tipizzazione statica forte e persino il controllo del tipo di runtime (sebbene questo aggiunga un sovraccarico). Tutti questi linguaggi non aggiungono solo tipi, ma aggiungono anche zucchero sintattico o persino la propria implementazione VM, che è scritta in JS.

Leggi l'intero articolo sulla rivista "System Administrator", n. 1-2 per il 2015 alle pagine 86-88.

Una versione PDF di questo numero può essere acquistata dal nostro negozio.

  1. Il sito web di Flow è http://flowtype.org.

In contatto con

È un wrapper modulare che genera un grafico delle dipendenze con tutti i moduli per un'applicazione JavaScript. Webpack impacchetta i moduli in uno o più piccoli pacchetti per il caricamento del browser. Inoltre, Webpack può essere utilizzato come lanciatore di attività in quanto analizza le dipendenze tra i moduli e genera risorse (asset). Puoi saperne di più sull'utilizzo di Webpack nei tuoi progetti nel nostro.

  • Grunt è un task runner progettato per automatizzare attività ripetitive e che richiedono molto tempo. Il suo ecosistema software ha un numero enorme di plugin (oltre 6000).
  • Gulp non è solo un altro task manager, ma uno strumento con un approccio interessante: definisce i compiti in JavaScript come funzioni, inoltre il GUl automatizza compiti dolorosi, offrendo un vasto ecosistema software (oltre 2.700 plugin), e fornisce anche una migliore trasparenza e controllo oltre il processo.
  • Browserify consente agli sviluppatori di software di utilizzare i moduli in stile NodeJS nei browser. Definisci le dipendenze e Broweserify racchiude tutto in un file JS ordinato.
  • Brunch.io è uno strumento che si concentra su velocità e semplicità. Viene fornito con una configurazione semplice e una documentazione dettagliata per iniziare rapidamente. Brunch genera automaticamente una mappa di file JS insieme ai fogli di stile CSS, facilitando il debug lato client.
  • Yeoman è uno strumento versatile che può essere utilizzato con quasi tutti i linguaggi di programmazione (JavaScript, Python, C#, Java e altri). Questo sistema di generazione di codice di base con un ricco ecosistema software (oltre 6200 plugin) viene utilizzato per lo sviluppo di applicazioni web. Con Yeoman puoi creare rapidamente nuovi progetti senza dimenticare di mantenere e migliorare quelli esistenti.
  • IDE e editor di codice

    • Swagger è un insieme di regole e strumenti per descrivere le API. Lo strumento è un'utilità indipendente dalla lingua. Ciò significa che Swagger crea una documentazione chiara leggibile sia da umani che da macchine, consentendo di automatizzare i processi dipendenti dalle API.
    • JSDoc è un insieme di strumenti che genera automaticamente documentazione di testo multipagina (HTML, JSON, XML, ecc.) dai commenti dal codice sorgente JavaScript. Questa applicazione può tornare utile per la gestione di progetti su larga scala.
    • jGrouseDoc (jGD) è uno strumento open source flessibile che consente agli sviluppatori di generare API dai commenti dal codice sorgente JavaScript. jGD documenta non solo variabili e funzioni, ma anche spazi dei nomi, interfacce, pacchetti e alcuni altri elementi.
    • YUIDoc è un'applicazione scritta in NodeJS. Utilizza una sintassi simile a Javadoc e Doxygen. Vanta anche supporto per l'anteprima dal vivo, supporto linguistico esteso e markup avanzato.
    • Docco è uno strumento di documentazione gratuito scritto in CoffeeScript "letterario". Crea un documento HTML per visualizzare i tuoi commenti intervallati da codice. Va notato che lo strumento supporta non solo JavaScript ma anche altre lingue. Ad esempio, Python, Ruby, Clojure e altri.

    Strumenti di test

    Gli strumenti di test JavaScript sono progettati per rilevare i bug durante lo sviluppo per evitare futuri bug degli utenti. Man mano che la complessità delle applicazioni personalizzate cresce, i test automatizzati non solo migliorano le prestazioni delle applicazioni, ma aiutano anche le aziende a mantenere il budget.

    • Jasmine è un framework di sviluppo guidato dal comportamento (BDD) per testare il codice JS. Non ha dipendenze esterne e non richiede l'esecuzione del DOM. Jasmine ha una sintassi chiara e diretta che rende i test più veloci e facili. Il framework può essere utilizzato anche per testare il codice Python e Ruby.
    • Mocha è un framework di test funzionale che viene eseguito su Node.js nel browser. Esegue i test in modo coerente per fornire report flessibili e accurati, rendendo i test asincroni facili e divertenti. Mocha è spesso usato insieme a Chai per controllare i risultati dei test.
    • PhantomJS viene spesso utilizzato per test front-end e unit test. Considerando che questo è qualcosa come WebKit "senza testa", gli script sono molto più veloci da eseguire. Include anche il supporto integrato per vari standard web. Ad esempio JSON, Canvas, gestione DOM, selettori SVG e CSS.
    • Protractor è un framework di test end-to-end scritto in Node.js per testare applicazioni AngularJS e Angular. È stato costruito su WebDriverJS e convalida le applicazioni come un utente finale utilizzando driver personalizzati ed eventi in linea.

    Strumenti di debug

    Il debug del codice è un processo laborioso e dispendioso in termini di tempo per gli sviluppatori JavaScript. Gli strumenti di debug sono particolarmente utili quando si lavora con migliaia di righe di codice. Molti degli strumenti di debug forniscono risultati abbastanza accurati.

    • JavaScript Debugger è uno strumento della Mozilla Developer Community (MDN) che può essere utilizzato come applicazione web autonoma per eseguire il debug del codice tra i browser. Firefox offre funzionalità locali e remote e la possibilità di eseguire il debug del codice su un dispositivo Android utilizzando Firefox per Android.
    • Chrome Dev Tools è un insieme di strumenti che include diverse utilità per il debug del codice JavaScript, la modifica dei CSS e il test delle prestazioni delle applicazioni.
    • ng-inspector è un'estensione cross-browser progettata per aiutare gli sviluppatori a scrivere, comprendere ed eseguire il debug di applicazioni AngularJS. L'utilità viene fornita con aggiornamenti in tempo reale, evidenziazione DOM, accesso diretto a regioni, modelli e altri elementi dell'applicazione.
    • Augury è un'estensione per il browser Google Chrome e per il debug delle applicazioni Angular 2. Consente agli sviluppatori di applicazioni Angular 2 di analizzare direttamente la struttura e le prestazioni dell'applicazione e di rilevare le modifiche.

    Strumenti di sicurezza

    • Snyk è uno strumento commerciale per rilevare, correggere e prevenire vulnerabilità note nelle applicazioni JavaScript, Java e Ruby. Il servizio dispone di un proprio database di vulnerabilità e estrae i dati da NSP e NIST NVD. Le patch e gli aggiornamenti offerti dall'azienda consentono agli sviluppatori di anticipare i rischi per la sicurezza.
    • Il Node Security Project offre strumenti utili per la scansione delle dipendenze e il rilevamento delle vulnerabilità. NSP utilizza il proprio database, basato sulla scansione del modulo npm, nonché i dati di database comuni come NIST NVD (National Vulnerability Database). Inoltre, NSP fornisce l'integrazione con GitHub Pull Request e il software CI. Sono inoltre disponibili scansioni in tempo reale, avvisi e consigli per eliminare le vulnerabilità nelle applicazioni Node.js.
    • RetireJS è un controllo delle dipendenze open source. Include vari componenti come scanner da riga di comando, plugin Grunt, estensioni Firefox e Chrome, plugin Burp e OWASP ZAP. Retirejs raccoglie informazioni sulla vulnerabilità dal NIST NVD e da altre fonti come bug tracker, blog e mailing list.
    • Gemnasium è uno strumento commerciale con una prova gratuita. Supporta una varietà di tecnologie e pacchetti tra cui Ruby, PHP, Bower (JavaScript), Python e npm (JavaScript). Lo strumento di sicurezza Gemnasium è dotato di funzioni utili come aggiornamenti automatici, avvisi in tempo reale, notifiche di sicurezza e integrazione con il servizio Slack.
    • OSSIndex supporta una varietà di ecosistemi (Java, JavaScript e .NET / C#) e molte piattaforme come NuGet, npm, Bower, Chocolatey, Maven, Composer, Drupal e MSI. Raccoglie informazioni sulla vulnerabilità dal National Vulnerability Database (NVD) e revisiona. Elabora anche le informazioni dei membri della comunità.

    Strumenti di analisi e ottimizzazione del codice

    Per verificare la qualità del codice, di solito si ricorre a test funzionali e unit test. Tuttavia, esiste un altro approccio che consente agli sviluppatori di verificare la qualità del codice e la sua conformità agli standard di codifica, ovvero l'analisi statica del codice.

    Attualmente, il software moderno combina strumenti per l'analisi del codice statico durante lo sviluppo al fine di escludere il codice di bassa qualità dall'ingresso in produzione.

    • JSLint è uno strumento di analisi web per il controllo della qualità del codice JavaScript. Una volta rilevato un problema all'origine, restituisce un messaggio con una descrizione del problema e una posizione approssimativa nel codice. JSLint è in grado di analizzare alcune norme di stile ed esporre errori di sintassi e problemi strutturali.
    • JSHint è uno strumento flessibile guidato dalla comunità per rilevare bug e potenziali problemi nel codice JS e JSHint è un fork di JSLint. Lo scopo principale di questo strumento di analisi del codice statico è aiutare gli sviluppatori JavaScript a lavorare su programmi complessi. È in grado di rilevare errori di sintassi, conversioni implicite di tipi di dati o variabili mancanti. Tuttavia, non può rilevare la velocità e la correttezza della tua applicazione, né può identificare i problemi di memoria nella tua applicazione. JSHint è un fork di JSLint.
    • ESLint è un linter open source per applicazioni web JSX e JavaScript. Ti aiuta a individuare schemi discutibili o a trovare codice che non corrisponde a stili specifici. Ciò consente agli sviluppatori di rilevare errori nel codice JS senza eseguirlo, risparmiando così tempo. Scritto in Node.js, lo strumento offre un runtime reattivo e un'installazione fluida tramite npm.
    • Flow è un controller di codice JavaScript statico sviluppato da Facebook. Utilizza annotazioni di tipo statico per verificare la presenza di errori nel codice. I tipi sono parametri impostati dagli sviluppatori e Flow verifica la conformità del software.

    Strumenti di controllo della versione

    • Negli ultimi anni, Git è diventato un sistema di controllo delle versioni ampiamente utilizzato per progetti sia piccoli che grandi. Questa utility gratuita offre velocità ed efficienza eccellenti. La sua popolarità è dovuta al suo sistema distribuito e ai vari tipi di controlli, nonché a un'area di staging in cui le versioni possono essere visualizzate in anteprima e formattate appena prima del completamento del commit.
    • Lo strumento Subversion, o SVN, ha guadagnato un'immensa popolarità ed è ancora ampiamente utilizzato in progetti e piattaforme open source come Python Apache o Ruby. Questo CVS è dotato di molte funzionalità per gestire varie operazioni (rinominare, copiare, eliminare, ecc.), unioni, blocco dei file e altro.

    Strumenti di gestione dei pacchetti e delle dipendenze

    L'elenco dei migliori strumenti di sviluppo JavaScript può continuare all'infinito. In questo articolo, hai visto solo gli strumenti popolari e affidabili che fungono da base per prodotti di qualità.

    E un insegnante di Netology, ha scritto una serie di articoli per il blog su EcmaScript6. Nella prima parte, esamineremo gli esempi di analisi del codice dinamico in EcmaScript utilizzando Iroh.js.

    Analisi del codice statico e dinamico

    Gli strumenti di analisi del codice sono uno strumento utile per rilevare e rilevare errori e peculiarità nel lavoro del codice. L'analisi del codice può essere statica e dinamica. Nel primo caso il codice sorgente viene analizzato e analizzato senza eseguirlo, nel secondo l'esecuzione avviene in un ambiente di sandboxing controllato, che fornisce meta-informazioni sugli elementi dell'applicazione durante la sua esecuzione.

    conclusioni

    Iroh.js è uno strumento potente e funzionale per l'analisi dinamica del codice in EcmaScript. Questo strumento può essere utilizzato sia per l'analisi del codice, inclusa la creazione di un grafico delle chiamate, la visualizzazione di tipi e valori effettivi in ​​variabili e oggetti, sia per la modifica del codice al volo, comprese le correzioni del codice in base agli eventi.

    L'analisi dinamica è un metodo piuttosto complesso, ma per EcmaScript, data la digitazione anatra, la presenza di oggetti host e funzioni native che consentono di modificare al volo il comportamento del codice, questo è l'unico modo per analizzare ed eseguire il debug del codice in fase di esecuzione. Iroh.js può anche utilizzare il codice per creare test funzionali senza doverlo modificare per esportare i valori.

    Non tutte le righe del mio codice sono perfette la prima volta. Beh, in alcuni casi... A volte... Ok, quasi mai. La verità è che passo molto più tempo a correggere i miei stupidi errori di quanto vorrei. Questo è il motivo per cui utilizzo analizzatori statici in quasi tutti i file JavaScript che scrivo.

    Gli analizzatori statici esaminano il tuo codice e trovano errori in esso prima di eseguirlo. Eseguono controlli semplici, come l'imposizione del controllo della sintassi (ad esempio, tabulazioni anziché spazi) e controlli più globali, come il controllo che le funzioni non siano eccessivamente complesse. Gli analizzatori statici cercano anche i bug che non possono essere trovati durante i test, ad esempio == invece di ===.


    In grandi progetti e quando si lavora in team di grandi dimensioni, è possibile utilizzare un piccolo aiuto per trovare bug "semplici", che in effetti si rivelano non così semplici come sembrano.


    JSLint, JSHint e compilatore di chiusura


    Esistono tre opzioni principali per gli analizzatori statici per JavaScript: JSLint, JSHint e Closure Compiler.



    JSLint è stato il primo analizzatore statico per JavaScript. Può essere eseguito sul sito ufficiale o utilizzare uno dei componenti aggiuntivi che possono essere eseguiti su file locali. JSLint trova molti bug importanti, ma è molto difficile. Ecco un primo esempio:



    var s = "mystring";
    per (var i = 0; i< s.length; i++) {
    console.log (s.charAt (i));
    }

    JSLint mostra due errori in questo codice:



    "++" inaspettato.
    Sposta le dichiarazioni "var" all'inizio della funzione.

    Il primo problema è la definizione della variabile i nelle condizioni del ciclo. JSLint inoltre non accetta l'operatore ++ alla fine della definizione del ciclo. Vuole che il codice assomigli a questo:



    var s = "mystring";
    variabile io;
    per (i = 0; i< s.length; i = i + 1) {
    console.log (s.charAt (i));
    }

    Apprezzo i creatori di JSLint, ma per me è eccessivo. Si è rivelata dura anche per Anton Kovalev, così ha creato JSHint.



    JSHint funziona come JSLint, ma è scritto in aggiunta a Node.js ed è quindi più flessibile. JSHint include un gran numero di opzioni, che ti consentono di eseguire controlli personalizzati scrivendo il tuo generatore di report.

    Puoi eseguire JSHint dal sito Web, ma nella maggior parte dei casi è meglio installare JSHint come strumento da riga di comando locale utilizzando Node.js. Una volta installato JSHint, puoi eseguirlo sui tuoi file con un comando come questo:



    jsint test.js

    JSHint include anche plugin per i più diffusi editor di testo in modo da poterlo eseguire mentre scrivi il codice.


    COMPILATORE DI CHIUSURA


    Il Closure Compiler di Google è un tipo di programma completamente diverso. Come suggerisce il nome, non è solo un programma di test, ma anche un compilatore. È scritto in Java e basato sul parser Rhino di Mozilla. Il compilatore di chiusura include una modalità semplice per eseguire il controllo del codice di base e modalità più complesse per eseguire controlli aggiuntivi e applicare definizioni di viste specifiche.


    Il compilatore di chiusura segnala errori nel codice JavaScript, ma genera anche versioni minificate di JavaScript. Il compilatore rimuove gli spazi bianchi, i commenti e le variabili inutilizzate e semplifica le espressioni lunghe per mantenere lo script il più compatto possibile.


    Google ha reso disponibile in rete una versione molto semplice del compilatore, ma molto probabilmente vorrai scaricare Closure Compiler ed eseguirlo localmente.


    Closure Compiler, dopo aver controllato il codice, emette un elenco di file in un file minimizzato. Quindi puoi eseguirlo scaricando il file compiler.jar.



    java -jar compiler.jar --js_output_file compress.js --js test1.js --js test2.js

    Scegliere il giusto programma di verifica


    Nei miei progetti combino Closure Compiler e JSHint. Closure Compiler esegue la minimizzazione e la convalida di base, mentre JSHint esegue un'analisi del codice più complessa. Questi due programmi funzionano alla grande insieme e ciascuno di essi copre aree che l'altro non può. Inoltre, posso utilizzare l'estensione JSHint per scrivere validatori personalizzati. Un programma generico che ho scritto testa alcune funzioni che non mi servono, come chiamare funzioni che non dovrebbero essere nel mio progetto.


    Ora che abbiamo esaminato alcuni programmi da controllare, analizziamo parte del codice errato. Ognuno di questi sei esempi è codice che non vale la pena scrivere e situazioni in cui i validatori di codice possono salvarti.


    Questo articolo utilizza JSHint per la maggior parte degli esempi, ma il compilatore di chiusura di solito genera avvisi simili.


    == o ===?


    JavaScript è un linguaggio tipizzato dinamicamente. Non è necessario definire i tipi mentre si scrive il codice ed esistono all'avvio.


    JavaScript offre due operatori di confronto per manipolare tali tipi dinamici: == e ===. Diamo un'occhiata a questo con un esempio.



    variabile n = 123;
    vars = "123";

    se (n == s) (
    alert ("Le variabili sono uguali");
    }

    se (n === s) (
    alert ("Le variabili sono identiche");
    }

    Operatore di confronto == Sono i resti del linguaggio C in cui JavaScript ha le sue radici. Il suo utilizzo è quasi sempre un errore: confrontare i valori separatamente dai tipi è raramente qualcosa che uno sviluppatore vuole davvero fare. Infatti, il numero "centoventitre" è diverso dalla stringa "uno due tre". Questi operatori sono facili da scrivere in modo errato e ancora più facili da interpretare. Controlla questo codice con JSHint e ottieni questo:

    test.js: riga 9, col 12, previsto "===" e invece visto "==".

    Variabili non definite e definizioni tardive


    Iniziamo con un semplice codice:



    test di funzionalita () (
    var myVar = "Ciao, mondo";
    console.log (myvar);
    }

    Vedi il bug? Faccio questo errore ogni volta. Esegui questo codice e ottieni l'errore:



    Errore di riferimento: myvar non è definito

    Rendiamo il problema un po' più complicato:



    test di funzionalita () (
    myVar = "Ciao, mondo";
    console.log (myVar);
    }

    Esegui questo codice e ottieni questo:



    Ciao mondo

    Questo secondo esempio funziona, ma ha effetti collaterali molto inaspettati. Le regole per definire le variabili e l'ambito JavaScript sono quanto meno confuse. Nel primo caso, JSHint riporterà quanto segue:

    test.js: riga 3, col 17, "myvar" non è definita.

    Nel secondo caso, riporterà questo:



    test.js: riga 2, col 5, "myVar" non è definita.
    test.js: riga 3, col 17, "myVar" non è definita.

    Il primo esempio ti aiuterà a evitare un errore di runtime. Non è necessario testare la tua applicazione: JSHint troverà l'errore per te. Il secondo esempio è peggiore, poiché non troverai un bug come risultato del test.


    Il problema nel secondo esempio è insidiosamente sottile e complesso. La variabile myVar è ora scomparsa dal suo ambito e si è spostata nell'ambito globale. Ciò significa che esisterà e avrà il valore Hello, World anche dopo l'esecuzione della funzione di test. Questo è chiamato inquinamento di portata globale.


    La variabile myVar esisterà per ogni altra funzione eseguita dopo la funzione di test. Eseguire il codice seguente dopo aver eseguito la funzione di test:



    console.log ("myVar:" + myVar);

    Riceverai comunque Hello, World. La variabile myVar si bloccherà nel tuo codice come un modello, il che porta a bug complessi che cercherai tutta la notte prima del rilascio, tutto perché hai dimenticato di scrivere var.


    Questa voce è passata attraverso il servizio RSS full-text - se questo è il tuo contenuto e "lo stai leggendo sul sito di qualcun altro", leggi le FAQ su http://ift.tt/jcXqJW.


    Non tutte le righe del mio codice sono perfette la prima volta. Beh, in alcuni casi... A volte... Ok, quasi mai. La verità è che passo molto più tempo a correggere i miei stupidi errori di quanto vorrei. Questo è il motivo per cui utilizzo analizzatori statici in quasi tutti i file JavaScript che scrivo.

    Gli analizzatori statici esaminano il tuo codice e trovano errori in esso prima di eseguirlo. Eseguono controlli semplici, come l'imposizione del controllo della sintassi (ad esempio, tabulazioni anziché spazi) e controlli più globali, come il controllo che le funzioni non siano eccessivamente complesse. Gli analizzatori statici cercano anche i bug che non possono essere trovati durante i test, ad esempio == invece di ===.

    In grandi progetti e quando si lavora in team di grandi dimensioni, è possibile utilizzare un piccolo aiuto per trovare bug "semplici", che in effetti si rivelano non così semplici come sembrano.

    JSLint, JSHint e compilatore di chiusura

    Esistono tre opzioni principali per gli analizzatori statici per JavaScript: JSLint, JSHint e Closure Compiler.

    JSLint è stato il primo analizzatore statico per JavaScript. Può essere eseguito sul sito ufficiale o utilizzare uno dei componenti aggiuntivi che possono essere eseguiti su file locali. JSLint trova molti bug importanti, ma è molto difficile. Ecco un primo esempio:

    Var s = "mystring"; per (var i = 0; i< s.length; i++) { console.log(s.charAt(i)); }

    JSLint mostra due errori in questo codice:

    "++" inaspettato. Sposta le dichiarazioni "var" all'inizio della funzione.

    Il primo problema è la definizione della variabile i nelle condizioni del ciclo. JSLint inoltre non accetta l'operatore ++ alla fine della definizione del ciclo. Vuole che il codice assomigli a questo:

    Var s = "mystring"; variabile io; per (i = 0; i< s.length; i = i + 1) { console.log(s.charAt(i)); }

    Apprezzo i creatori di JSLint, ma per me è eccessivo. Si è rivelata dura anche per Anton Kovalev, così ha creato JSHint.

    JSHint funziona come JSLint, ma è scritto in aggiunta a Node.js ed è quindi più flessibile. JSHint include un gran numero di opzioni, che ti consentono di eseguire controlli personalizzati scrivendo il tuo generatore di report.
    Puoi eseguire JSHint dal sito Web, ma nella maggior parte dei casi è meglio installare JSHint come strumento da riga di comando locale utilizzando Node.js. Una volta installato JSHint, puoi eseguirlo sui tuoi file con un comando come questo:

    Jsint test.js

    JSHint include anche plugin per i più diffusi editor di testo in modo da poterlo eseguire mentre scrivi il codice.

    COMPILATORE DI CHIUSURA

    Il Closure Compiler di Google è un tipo di programma completamente diverso. Come suggerisce il nome, non è solo un programma di test, ma anche un compilatore. È scritto in Java e basato sul parser Rhino di Mozilla. Il compilatore di chiusura include una modalità semplice per eseguire il controllo del codice di base e modalità più complesse per eseguire controlli aggiuntivi e applicare definizioni di viste specifiche.

    Il compilatore di chiusura segnala errori nel codice JavaScript, ma genera anche versioni minificate di JavaScript. Il compilatore rimuove gli spazi bianchi, i commenti e le variabili inutilizzate e semplifica le espressioni lunghe per mantenere lo script il più compatto possibile.

    Google ha reso disponibile in rete una versione molto semplice del compilatore, ma molto probabilmente vorrai scaricare Closure Compiler ed eseguirlo localmente.

    Closure Compiler, dopo aver controllato il codice, emette un elenco di file in un file minimizzato. Quindi puoi eseguirlo scaricando il file compiler.jar.

    Java -jar compiler.jar --js_output_file compress.js --js test1.js --js test2.js

    Scegliere il giusto programma di verifica

    Nei miei progetti combino Closure Compiler e JSHint. Closure Compiler esegue la minimizzazione e la convalida di base, mentre JSHint esegue un'analisi del codice più complessa. Questi due programmi funzionano alla grande insieme e ciascuno di essi copre aree che l'altro non può. Inoltre, posso utilizzare l'estensione JSHint per scrivere validatori personalizzati. Un programma generico che ho scritto testa alcune funzioni che non mi servono, come chiamare funzioni che non dovrebbero essere nel mio progetto.

    Ora che abbiamo esaminato alcuni programmi da controllare, analizziamo parte del codice errato. Ognuno di questi sei esempi è codice che non vale la pena scrivere e situazioni in cui i validatori di codice possono salvarti.

    Questo articolo utilizza JSHint per la maggior parte degli esempi, ma il compilatore di chiusura di solito genera avvisi simili.

    == o ===?

    JavaScript è un linguaggio tipizzato dinamicamente. Non è necessario definire i tipi mentre si scrive il codice ed esistono all'avvio.

    JavaScript offre due operatori di confronto per manipolare tali tipi dinamici: == e ===. Diamo un'occhiata a questo con un esempio.

    Var n = 123; vars = "123"; if (n == s) (alert ("Le variabili sono uguali");) if (n === s) (alert ("Le variabili sono identiche");)

    Operatore di confronto == sono i resti del linguaggio C in cui JavaScript ha le sue radici. Il suo utilizzo è quasi sempre un errore: confrontare i valori separatamente dai tipi è raramente qualcosa che uno sviluppatore vuole davvero fare. Infatti, il numero "centoventitre" è diverso dalla stringa "uno due tre". Questi operatori sono facili da scrivere in modo errato e ancora più facili da interpretare. Controlla questo codice con JSHint e ottieni questo:

    Test.js: riga 9, col 12, previsto "===" e invece visto "==".

    Variabili non definite e definizioni tardive

    Iniziamo con un semplice codice:

    Test di funzione () (var myVar = "Hello, World"; console.log (myvar);)

    Vedi il bug? Faccio questo errore ogni volta. Esegui questo codice e ottieni l'errore:

    Errore di riferimento: myvar non è definito

    Rendiamo il problema un po' più complicato:

    Test di funzione () (myVar = "Hello, World"; console.log (myVar);)

    Esegui questo codice e ottieni questo:

    Ciao mondo

    Questo secondo esempio funziona, ma ha effetti collaterali molto inaspettati. Le regole per definire le variabili e l'ambito JavaScript sono quanto meno confuse. Nel primo caso, JSHint riporterà quanto segue:

    Test.js: riga 3, col 17, "myvar" non è definita.

    Nel secondo caso, riporterà questo:

    Test.js: riga 2, col 5, "myVar" non è definita. test.js: riga 3, col 17, "myVar" non è definita.

    Il primo esempio ti aiuterà a evitare un errore di runtime. Non è necessario testare la tua applicazione: JSHint troverà l'errore per te. Il secondo esempio è peggiore, poiché non troverai un bug come risultato del test.

    Il problema nel secondo esempio è insidiosamente sottile e complesso. La variabile myVar è ora scomparsa dal suo ambito e si è spostata nell'ambito globale. Ciò significa che esisterà e avrà il valore Hello, World anche dopo l'esecuzione della funzione di test. Questo è chiamato inquinamento di portata globale.

    La variabile myVar esisterà per ogni altra funzione eseguita dopo la funzione di test. Eseguire il codice seguente dopo aver eseguito la funzione di test:

    Console.log ("myVar:" + myVar);

    Riceverai comunque Hello, World. La variabile myVar si bloccherà nel tuo codice come un modello, il che porta a bug complessi che cercherai tutta la notte prima del rilascio, tutto perché hai dimenticato di scrivere var.