JSLint
JSLint je nástroj pro kontrolu kvality kódu. Jeho autorem je známý vývojář a propagátor Douglas Crockford (bude hostem na letošním WebExpo – pozn.red.). Nástroj JSLint provede statickou analýzu a upozorní na místa, která by mohla způsobit problémy. Používání JSLintu nutí programátora dodržovat určité konvence. Výsledkem je kód, u něhož je konzistentní coding standard, což pomáhá eliminovat mnohé zásadní chyby.
Abychom si udělali lepší představu o tom, co JSLint dokáže, přejdeme rovnou k jednoduchému příkladu. Představme si, že náš zdrojový kód obsahuje mimo jiné tuto podmínku (s „chybou“):
if (a = b) { // nejaky korektni kod }
Bystrý čtenář si povšimne, že došlo zřejmě k chybě z nepozornosti či k překlepu a proměnné se v podmínce neporovnají, ale přiřazují. JSLint v takovém případě vypíše pozici chyby a zprávu:
Expected a conditional expression and instead saw an assignment.
Instalace a použití
JSLint existuje jako online nástroj (JSLint online), ale lze jej použít i offline. Stáhněte si aktuální verzi z GitHubu:
git clone https://github.com/douglascrockford/JSLint
V aktuálním adresáři se vytvoří adresář se staženým projektem. Hlavní soubor, který nás zajímá, je jslint.js
. V něm se nachází globální funkce JSLINT. Použití s implicitním nastavením je snadné:
var myResult = JSLINT(source, options);
V proměnné source
se nachází řetězec s kódem určeným ke kontrole. V myResult bude hodnota true
, pokud byl kód podle JSLint správný, jinak false
. V globálně dostupném poli JSLINT.errors budou pak jednotlivé chyby, vždy s číslem řádku, popisem problému a dalšími informacemi.
Druhý parametr je volitelný parametr, který obsahuje nastavení pravidel.
Používáte-li nějaký specializovaný editor, může být JSLint dostupný jako plugin. Některé pluginy do editorů mohou mít ale jiné nastavení, např. plugin pro VIM nevyžaduje mezeru za ‚if‘ a naopak chce středník za každým příkazem.
Podívejme se teď na část pravidel, které JSLint obsahuje. A nezapomeňte na autorovo varování: JSLint will hurt your feelings.
Typová kontrola
var i = 0; i = "a";
Type confusion: 'i': number and 'a': string.
Přestože JavaScript není staticky typovaný jazyk, JSLint dokáže v tomto případě rozpoznat, že jste do číselné proměnné chtěli uložit řetězec.
Operace inkrementace a dekrementace
Tyto operace jsou zakázány, neboť bývají zdrojem záludných chyb. Jsou povolené jen v cyklu for.
Vytváření objektů
var a = new Object();
Use the object literal notation {}.
JSLint vyžaduje specifický zápis pro nové objekty. Proč nám nutí jinou notaci, když je to „to samé“? Důvody jsou následující:
- syntaxe je mnohem kratší
- elegantněji se vytvářejí objekty za běhu:
{name: "Bob", age: 8}
Povinné středníky
var foo = function () { //... }
Středníky jsou v JavaScriptu nepovinné (resp. existují poměrně komplikovaná pravidla, která říkají, kde si má interpret středník „domyslet“). Výsledkem je, že pokud k předchozímu kódu připíšete něco takového:
(function () { //... })();
bude celý kód interpretován jako
var foo = function () { //... }(function () { //... })();
Druhá funkce se stane parametrem pro volání té první, a výsledek se bude volat jako funkce. Tedy něco jiného, než jsme zamýšleli. Proto JSLint na střednících trvá.
Eval je zlo
Přiznejme si, že spouštět kód v řetězci není úplně nejčistší řešení. Kód v řetězci není vizuálně strukturovaný, editory běžně nezvýrazňují syntax JavaScriptu v řetězcích, a to ani nemluvíme o možných bezpečnostních rizicích, spojených s neošetřeným vstupem funkce eval().
Nedosažitelný kód
JSLint kontroluje, zda za příkazy jako return
, které „odkloní“ běh programu, není nějaký další kód. Pokud je, upozorní na to.
JSLint dovede uživatele zahltit slušnou řádkou zpráv i při poměrně banální chybě. Vyplatí se nejdřív podívat na daný řádek a zamyslet se, co je špatně, než mechanicky chybu po chybě napravovat.
Některá varování JSLint mohou být až nesmyslná a mohou vás pěkně vytočit. Dejte ale Douglasovi šanci a najděte si, co to varování znamená – většinou má nějaký smysl. Pokud vám ale některá varování opravdu nevyhovují a považujete je v dané situaci (nebo obecně) za nesmyslná, můžete některá z nich potlačit v konfiguraci.
Závěrem: JSLint nám dává možnost zamyslet se nad způsobem, jakým píšeme v JavaScriptu, a nad návrhem jazyka ECMAScript jako takového.
JSHint
Jestliže se vám zdá JSLint příliš radikální a omezujíci, JSHint by mohlo být to pravé. Jeho autory rozčiloval fakt, že JSLint nutil programátory psát jako Douglas Crockford. Proto vznikl fork z verze 2010–12–16. Ten je méně pedantický a dostal jméno JSHint. Jeho vývoj je řízený komunitou a klade důraz především na respektování odlišných programovacích stylů. Je možné nastavit kontrolu každého pravidla, které chceme dodržovat.
git clone https://github.com/jshint/jshint.git
Použití offline verze je stejné jako u JSLint, jen se používá funkce JSHINT.
Konstrukce, které JSLint zakazoval, je možné v JSHint povolit. Například operátor přiřazení v podmínce, podmínka bez složených závorek, funkce eval… Navíc je u JSHint možné specifikovat i prostředí (prohlížeč, jQuery/Prototype atd.), které používáme. JSHint tak rozpozná příslušné globální proměnné a nehlásí „planý poplach“.
Jako materiál pro článek byla použita JSLint edice 2011–07–01, JSHint edice 2011–04–16, Ubuntu 11.04.
- http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/
- http://stackoverflow.com/questions/444080/do-you-recommend-using-semicolons-after-every-statement-in-javascripto
- http://anton.kovalyov.net/2011/02/20/why-i-forked-jslint-to-jshint/
- http://zdrojak.root.cz/zpravicky/staticka-kontrola-javascriptu-zeon-js/
- http://zdrojak.root.cz/zpravicky/javascript-doctor-vyzna-se-i-ve-vasem-kodu/
- http://zdrojak.root.cz/zpravicky/jshint-novy-kontroler-syntakticke-spravnosti-javascriptu/