Компютри Windows интернет

JavaScript сигурност или как да напишете защитен JS код. Инструменти за контрол на версиите

АЛЕКСАНДЪР МАЙОРОВ,програмист, 11 години опит в програмирането, седем от които посвети на разработка за мобилни устройства

Статичен тип анализ в JavaScript
Изпробвайте Facebook Flow Analyzer

Facebook представи нов проект с отворен код Flow - статичен код анализатор за JavaScript. Основната цел на разработката на анализатора е да опрости търсенето на грешки.

В допълнение, Flow предоставя синтактично разширение на JavaScript в стил TypeScript за изрично посочване на типове. Поддържат се много от новите функции, въведени в спецификацията ECMAScript 6.

Често се засяга темата за въвеждане на езици за програмиране. Това е предмет на холивари и определяне на положителните или отрицателните черти на даден език. Напоследък много се говори за писане в JavaScript. Някой го харесва такъв, какъвто е. Хората, запознати с други езици за програмиране, особено тези със силно изрично въвеждане, смятат този подход за „граната в ръцете на маймуна“. Всички знаем, че JavaScript е слабо динамично въведен език. Гурутата на Front-end разработката са се научили как да използват това в своя полза, но кодът понякога е твърде тежък за разбиране. Тези, които току-що идват в света на програмирането с JavaScript, са объркани от магията, която интерпретаторът прави, и често улавят грешки от небето. Но първо, нека се поразровим малко за писането като цяло. какво е то?

Писане на езици за програмиране

Чрез въвеждане, езиците за програмиране се разделят на два големи лагера - въведени и ненапечатани. Например въведените езици включват такива езици като C, Python, PHP, Lua, JavaScript. Примери за нетипизирани езици: асемблер, Forth, Brainfuck. Да Да точно. JavaScript, подобно на много други интерпретирани езици, се въвежда. Следователно в никакъв случай не казвайте, че е ненапечатан. Особено на интервюта за работа.

На свой ред въведените езици са разделени на няколко припокриващи се категории:

  • Статично или динамично въведени.
  • Силно или свободно написано.
  • Изрично или имплицитно въведени.

Статично въведени езици

При статичното типизиране крайните типове променливи и функции се задават по време на компилиране. Компилаторът коригира вашите грешки при несъответствие на типа дори преди стартирането на програмата. Примери за езици: C, Java, C #.

Динамично въведени езици

При динамично писане всички типове се откриват по време на изпълнение. И ако направите грешка, ще разберете за нея едва когато стартирате програмата. Ето защо, когато пишете динамично, е много важно да обърнете специално внимание на проверката и улавянето на грешки. Примери за езици: JavaScript, PHP, Python, Ruby.

Силно писане (силно)

Силно въведените езици не позволяват смесване на различни типове в изрази и няма да извършват автоматични неявни преобразувания. Например, не можете да извадите число или друг тип, различен от низ от низ. Примери за езици: Java, Python, Haskell, Lisp.

Леко писане (слабо)

Неправилно въведените езици извършват много неявни преобразувания автоматично. Те правят това, дори ако може да възникне загуба на прецизност или преобразуване, двусмислено. Примери за езици: PHP, JavaScript, Visual Basic.

Изрично въвеждане

В изрично въведени езици, типът на новите променливи/функции и аргументи трябва да бъдат посочени изрично. Примери за езици: C ++, D, C #.

Неявно въвеждане

При езици с имплицитно въвеждане задачата за посочване на типовете се прехвърля на компилатора / интерпретатора. Примери за езици: JavaScript, PHP, Lua. В такива езици, като правило, обектите имат специални методи, които се извикват при прехвърляне към тип. Например, PHP има метод _toString (), а JavaScript има метод със същото име, но без долно черта, - toString (). Тези методи се извикват, когато обект се прехвърля към низов тип. Понякога такива методи се наричат ​​магия (всеки неявни процеси винаги са магия).

Важно е да се отбележи, че всички тези категории се припокриват. Въз основа на тези категории виждаме, че JavaScript се въвежда динамично имплицитно. И ако говорим преувеличено, тогава природата на езика може да бъде описана по следния начин: във всяка неразбираема ситуация приведете всичко до примитиви, главно до линия. Въпреки че в действителност всичко е малко по-сложно, сега няма да навлизаме в подробности.

„Защо ни трябва да пишем?“ - може да попитате. JavaScript живее добре без него в продължение на 20 години. Отговорът е прост: JavaScript никога не е бил използван за решаване на сложни проблеми на ниво предприятие. Сега този език надхвърли браузъра и навлезе в бекенд територията. Когато пишете голямо приложение, става трудно да се уловят грешки, които често са свързани с кастинг.

JavaScript добавки

Тъй като JavaScript се изпълнява от страна на клиента (в браузърите), една от опциите за решаване на проблема е да се създаде език – диалект, който ще бъде компилиран в JS. Той действа като асемблер.

Появиха се езици като TypeScript, Dart, AtScript, които добавят статично силно въвеждане и дори проверка на типа по време на изпълнение (въпреки че това добавя допълнителни разходи). Всички тези езици не просто добавят типове, но също така добавят или синтактична захар, или дори собствена реализация на VM, която е написана на JS.

Прочетете цялата статия в списание "Системен администратор", No 1-2 за 2015 г. на стр. 86-88.

PDF версия на този брой може да бъде закупена от нашия магазин.

  1. Уебсайтът на Flow е http://flowtype.org.

Във връзка с

Това е модулна обвивка, която генерира графика на зависимост с всички модули за JavaScript приложение. Webpack пакетира модулите в един или повече малки пакета за зареждане на браузъра. В допълнение, Webpack може да се използва като средство за стартиране на задачи, тъй като анализира зависимостите между модулите и генерира ресурси (активи). Можете да научите повече за използването на Webpack във вашите проекти в нашия.

  • Grunt е бегач на задачи, предназначен да автоматизира повтарящи се и отнемащи време задачи, които отнемат много време. Неговата софтуерна екосистема има огромен брой плъгини (над 6000).
  • Gulp не е просто още един мениджър на задачи, а инструмент с интересен подход: той дефинира задачите в JavaScript като функции, също така GUl автоматизира болезнени задачи, предлагайки обширна софтуерна екосистема (над 2700 плъгина) и също така осигурява по-добра прозрачност и контрол над процеса.
  • Browserify позволява на разработчиците на софтуер да използват модули в стил NodeJS в браузърите. Вие дефинирате зависимостите и Broweserify пакетира всичко в чист JS файл.
  • Brunch.io е инструмент, който се фокусира върху скоростта и простотата. Предлага се с проста конфигурация и подробна документация, за да започнете бързо. Brunch автоматично генерира карта на JS файлове заедно с CSS стилове, което улеснява отстраняването на грешки от страна на клиента.
  • Yeoman е универсален инструмент, който може да се използва с почти всеки език за програмиране (JavaScript, Python, C #, Java и други). Тази основна система за генериране на код с богата софтуерна екосистема (над 6200 плъгина) се използва за разработване на уеб приложения. С Yeoman можете бързо да създавате нови проекти, без да забравяте да поддържате и подобрявате съществуващите.
  • IDE и редактори на код

    • Swagger е набор от правила и инструменти за описание на API. Инструментът е независима от езика помощна програма. Това означава, че Swagger създава ясна документация, която може да се чете както от хора, така и от машини, което ви позволява да автоматизирате зависими от API процеси.
    • JSDoc е набор от инструменти, който автоматично генерира многостранична текстова документация (HTML, JSON, XML и др.) от коментари от изходния код на JavaScript. Това приложение може да бъде полезно за управление на мащабни проекти.
    • jGrouseDoc (jGD) е гъвкав инструмент с отворен код, който позволява на разработчиците да генерират API от коментари от изходния код на JavaScript. jGD документира не само променливи и функции, но и пространства от имена, интерфейси, пакети и някои други елементи.
    • YUIDoc е приложение, написано на NodeJS. Той използва синтаксис, подобен на Javadoc и Doxygen. Той също така може да се похвали с поддръжка за предварителен преглед на живо, разширена езикова поддръжка и разширено маркиране.
    • Docco е безплатен инструмент за документация, написан на "литературен" CoffeeScript. Той създава HTML документ за показване на вашите коментари, разпръснати с код. Трябва да се отбележи, че инструментът поддържа не само JavaScript, но и други езици. Например Python, Ruby, Clojure и други.

    Инструменти за тестване

    Инструментите за тестване на JavaScript са предназначени да улавят грешки по време на разработката, за да се избегнат бъдещи потребителски грешки. С нарастването на сложността на персонализираните приложения автоматизираните тестове не само подобряват производителността на приложенията, но и помагат на компаниите да запазят бюджета.

    • Jasmine е рамка за развитие, управлявана от поведението (BDD) за тестване на JS код. Той няма външни зависимости и не изисква DOM да работи. Jasmine има изчистен и ясен синтаксис, който прави тестването по-бързо и по-лесно. Рамката може да се използва и за тестване на Python и Ruby код.
    • Mocha е функционална тестова рамка, която работи на Node.js в браузъра. Той провежда тестове последователно, за да осигури гъвкаво и точно отчитане, което прави асинхронните тестове забавни и лесни. Мока често се използва заедно с Chai за проверка на резултатите от теста.
    • PhantomJS често се използва за тестове за преден край и модулни тестове. Като се има предвид, че това е нещо като "безглавен" WebKit, скриптовете се изпълняват много по-бързо. Той също така включва вградена поддръжка за различни уеб стандарти. Например JSON, Canvas, DOM обработка, SVG и CSS селектори.
    • Protractor е рамка за тестване от край до край, написана на Node.js за тестване на AngularJS и Angular приложения. Той е изграден върху WebDriverJS и валидира приложения като краен потребител, използвайки персонализирани драйвери и вградени събития.

    Инструменти за отстраняване на грешки

    Отстраняването на грешки в кода е трудоемък и отнемащ време процес за разработчиците на JavaScript. Инструментите за отстраняване на грешки са особено полезни при работа с хиляди редове код. Много от инструментите за отстраняване на грешки предоставят доста точни резултати.

    • JavaScript Debugger е инструмент от общността на разработчиците на Mozilla (MDN), който може да се използва като самостоятелно уеб приложение за отстраняване на грешки в код в различни браузъри. Firefox предлага локална и отдалечена функционалност и възможност за отстраняване на грешки в код на устройство с Android с помощта на Firefox за Android.
    • Chrome Dev Tools е набор от инструменти, който включва няколко помощни програми за отстраняване на грешки в JavaScript код, редактиране на CSS и тестване на производителността на приложението.
    • ng-inspector е разширение за различни браузъри, предназначено да помогне на разработчиците да пишат, разбират и отстраняват грешки в AngularJS приложения. Помощната програма идва с актуализации в реално време, подчертаване на DOM, директен достъп до региони, модели и други елементи на приложението.
    • Augury е разширение за браузъра Google Chrome и за отстраняване на грешки в приложенията на Angular 2. То позволява на разработчиците на приложения на Angular 2 директно да анализират структурата и производителността на приложението и да откриват промени.

    Инструменти за сигурност

    • Snyk е търговски инструмент за откриване, коригиране и предотвратяване на известни уязвимости в JavaScript, Java и Ruby приложения. Услугата има собствена база данни за уязвимости и изтегля данни от NSP и NIST NVD. Пачовете и актуализациите, предлагани от компанията, позволяват на разработчиците да предвидят рискове за сигурността.
    • Проектът за сигурност на Node предлага полезни инструменти за сканиране на зависимости и откриване на уязвимости. NSP използва собствена база данни, изградена върху сканиране на npm модул, както и данни от общи бази данни като NIST NVD (Национална база данни за уязвимости). В допълнение, NSP осигурява интеграция с GitHub Pull Request и CI софтуер. Има също сканиране в реално време, предупреждения и препоръки за елиминиране на уязвимости в приложенията Node.js.
    • RetireJS е средство за проверка на зависимости с отворен код. Включва различни компоненти като скенер за команден ред, плъгин Grunt, разширения за Firefox и Chrome, Burp плъгини и OWASP ZAP. Retirejs събира информация за уязвимости от NIST NVD и други източници, като проследяващи грешки, блогове и пощенски списъци.
    • Gemnasium е търговски инструмент с безплатна пробна версия. Той поддържа различни технологии и пакети, включително Ruby, PHP, Bower (JavaScript), Python и npm (JavaScript). Инструментът за сигурност Gemnasium се предлага с полезни функции като автоматични актуализации, сигнали в реално време, известия за сигурност и интеграция с услугата Slack.
    • OSSIndex поддържа различни екосистеми (Java, JavaScript и .NET / C #) и много платформи като NuGet, npm, Bower, Chocolatey, Maven, Composer, Drupal и MSI. Той събира информация за уязвимостите от Националната база данни за уязвимости (NVD) и преглежда. Той също така обработва информация от членове на общността.

    Инструменти за анализ и оптимизиране на кода

    За да проверите качеството на кода, обикновено се обръща към функционално тестване и тестване на модули. Има обаче друг подход, който позволява на разработчиците да проверят качеството на кода и съответствието му със стандартите за кодиране, а именно статичен анализ на кода.

    В момента съвременният софтуер съчетава инструменти за анализ на статичен код по време на разработката, за да изключи нискокачествен код от навлизане в производството.

    • JSLint е уеб аналитичен инструмент за проверка на качеството на JavaScript кода. След като открие проблем в източника, той връща съобщение с описание на проблема и приблизително местоположение в кода. JSLint е в състояние да анализира някои стилови норми и да разкрие синтактични грешки и структурни проблеми.
    • JSHint е гъвкав инструмент, управляван от общността, за откриване на грешки и потенциални проблеми във вашия JS код, а JSHint е разклонение на JSLint. Основната цел на този инструмент за статичен код за анализ е да помогне на разработчиците на JavaScript, работещи върху сложни програми. Той е в състояние да открива синтактични грешки, имплицитни преобразувания на тип данни или липсваща променлива. Въпреки това, той не може да открие скоростта и коректността на вашето приложение, нито може да идентифицира проблеми с паметта във вашето приложение. JSHint е разклонение от JSLint.
    • ESLint е линтер с отворен код за JSX и JavaScript уеб приложения. Помага ви да откриете съмнителни модели или да намерите код, който не съответства на конкретни стилове. Това позволява на разработчиците да откриват грешки в JS кода, без да го изпълняват, като по този начин спестяват време. Написан на Node.js, инструментът предлага отзивчиво време за изпълнение и плавна инсталация чрез npm.
    • Flow е статичен JavaScript кодов контролер, разработен от Facebook. Той използва анотации от статичен тип, за да провери кода ви за грешки. Типовете са параметри, зададени от разработчиците, а Flow проверява вашия софтуер за съответствие.

    Инструменти за контрол на версиите

    • През последните години Git се превърна в широко използвана система за контрол на версиите както за малки, така и за големи проекти. Тази безплатна програма осигурява отлична скорост и ефективност. Популярността му се дължи на неговата разпределена система и различни видове контроли, както и на етапна зона, където версиите могат да бъдат визуализирани и форматирани непосредствено преди завършването на комита.
    • Инструментът Subversion, или SVN, придоби огромна популярност и все още се използва широко в проекти и платформи с отворен код като Python Apache или Ruby. Този CVS се предлага с много функции за управление на различни операции (преименуване, копиране, изтриване и т.н.), сливания, заключване на файлове и др.

    Инструменти за управление на пакети и зависимости

    Списъкът с най-добрите инструменти за разработка на JavaScript може да продължи безкрайно. В тази статия сте видели само популярните и надеждни инструменти, които служат като основа за качествени продукти.

    И учител по нетология, написа серия от статии за блога за EcmaScript6. В първата част ще разгледаме примерите за динамичен анализ на код в EcmaScript с помощта на Iroh.js.

    Статичен и динамичен кодов анализ

    Инструментите за анализ на кода са полезен инструмент за откриване и откриване на грешки и особености в работата на кода. Анализът на кода може да бъде статичен и динамичен. В първия случай изходният код се анализира и анализира без да се изпълнява, във втория, изпълнението се извършва в контролирана пясъчна среда, която предоставя мета-информация за елементите на приложението по време на неговото изпълнение.

    заключения

    Iroh.js е мощен и функционален инструмент за динамичен анализ на код в EcmaScript. Този инструмент може да се използва както за анализ на кода, включително изграждане на графика на повикванията, показване на действителни типове и стойности в променливи и обекти, така и за модификация на кода в движение, включително поправки на код въз основа на събития.

    Динамичният анализ е доста сложен метод, но за EcmaScript, като се има предвид типичното въвеждане, наличието на хост обекти и естествени функции, които ви позволяват да променяте поведението на кода в движение, това е единственият начин за анализиране и отстраняване на грешки в кода по време на изпълнение. Iroh.js може също да използва код за създаване на функционални тестове, без да се налага да го модифицира, за да експортира стойности.

    Не всеки ред от моя код е перфектен от първия път. Е, в някои случаи ... Понякога ... Добре - почти никога. Истината е, че прекарвам значително повече време в коригиране на собствените си глупави грешки, отколкото бих искал. Ето защо използвам статични анализатори в почти всеки JavaScript файл, който пиша.

    Статичните анализатори разглеждат вашия код и намират грешки в него, преди да го стартирате. Те извършват прости проверки, като налагане на проверка на синтаксиса (например табулатори вместо интервали) и по-глобални проверки, като проверка дали функциите не са прекалено сложни. Статичните анализатори също търсят грешки, които не могат да бъдат открити по време на тестване, например == вместо ===.


    В големи проекти и когато работите в големи екипи, можете да използвате малко помощ при намирането на такива „прости“ грешки, които всъщност се оказват не толкова прости, колкото изглеждат.


    JSLint, JSHint и Closure Compiler


    Има три основни опции за статични анализатори за JavaScript: JSLint, JSHint и Closure Compiler.



    JSLint беше първият статичен анализатор за JavaScript. Може да се стартира на официалния сайт или да се използва една от добавките, които могат да се изпълняват на локални файлове. JSLint открива много важни грешки, но е много труден. Ето един отличен пример:



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

    JSLint показва две грешки в този код:



    Неочаквано "++".
    Преместете декларациите "var" в горната част на функцията.

    Първият проблем е дефинирането на променливата i в условията на цикъла. JSLint също не приема оператора ++ в края на дефиницията на цикъла. Той иска кодът да изглежда така:



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

    Оценявам създателите на JSLint, но за мен това е излишно. Оказа се трудно и за Антон Ковалев, така че той създаде JSHint.



    JSHint работи по същия начин като JSLint, но е написан в допълнение към Node.js и следователно е по-гъвкав. JSHint включва голям брой опции, които ви позволяват да извършвате персонализирани проверки, като напишете свой собствен генератор на отчети.

    Можете да стартирате JSHint от уебсайта, но в повечето случаи е по-добре да инсталирате JSHint като локален инструмент за команден ред с помощта на Node.js. След като инсталирате JSHint, можете да го стартирате във вашите файлове с команда като тази:



    jshint test.js

    JSHint също така включва плъгини за популярни текстови редактори, така че можете да го стартирате, докато пишете своя код.


    ЗАТВАРЯВАЩ КОМПИЛАТОР


    Closure Compiler на Google е напълно различен вид програма. Както подсказва името му, това е не само тестова програма, но и компилатор. Написан е на Java и базиран на анализатора Rhino на Mozilla. Closure Compiler включва прост режим за извършване на основна проверка на кода и по-сложни режими за извършване на допълнителна проверка и налагане на специфични дефиниции на изглед.


    Компилаторът за затваряне отчита грешки в JavaScript кода, но също така генерира минимизирани версии на JavaScript. Компилаторът премахва интервалите, коментарите и неизползваните променливи и опростява дългите изрази, за да запази скрипта възможно най-компактен.


    Google направи много основна версия на компилатора достъпна в мрежата, но най-вероятно ще искате да изтеглите Closure Compiler и да го стартирате локално.


    Closure Compiler, след проверка на кода, извежда списък с файлове в един минимизиран файл. Така че можете да го стартирате, като изтеглите файла compiler.jar.



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

    Избор на правилната програма за проверка


    В моите проекти комбинирам Closure Compiler и JSHint. Closure Compiler прави минимизиране и основно валидиране, докато JSHint прави по-сложен анализ на кода. Тези две програми работят чудесно заедно и всяка от тях покрива области, които другата не може. Освен това мога да използвам разширението JSHint, за да пиша персонализирани валидатори. Една обща програма, която написах, тества определени функции, които не са ми необходими, като например извикване на функции, които не трябва да са в моя проект.


    След като разгледахме няколко програми за проверка, нека разбием някои от лошия код. Всеки от тези шест примера е код, който не си струва да се пише и ситуации, в които валидаторите на код могат да ви спасят.


    Тази статия използва JSHint за повечето примери, но Closure Compiler обикновено генерира подобни предупреждения.


    == или ===?


    JavaScript е динамично въведен език. Не е нужно да дефинирате типове, докато пишете кода си и те съществуват при стартиране.


    JavaScript предлага два оператора за сравнение за манипулиране на такива динамични типове: == и ===. Нека да разгледаме това с пример.



    var n = 123;
    var s = "123";

    ако (n == s) (
    предупреждение ("Променливите са равни");
    }

    ако (n === s) (
    предупреждение („Променливите са идентични“);
    }

    Оператор за сравнение == Дали са остатъците от езика C, в който JavaScript има своите корени. Използването му почти винаги е грешка: сравняването на стойности отделно от типове рядко е нещо, което разработчикът всъщност иска да направи. Всъщност числото "сто двадесет и три" е различно от низа "едно две три". Тези оператори са лесни за правописна грешка и дори по-лесно за грешно разчитане. Проверете този код с JSHint и ще получите това:

    test.js: ред 9, колона 12, Очаквано "===" и вместо това видях "==".

    Недефинирани променливи и късни дефиниции


    Нека започнем с малко прост код:



    функционален тест () (
    var myVar = "Здравей, свят";
    console.log (myvar);
    }

    Виждате ли грешката? Правя тази грешка всеки път. Изпълнете този код и получавате грешката:



    ReferenceError: myvar не е дефиниран

    Нека направим проблема малко по-сложен:



    функционален тест () (
    myVar = "Здравей, свят";
    console.log (myVar);
    }

    Изпълнете този код и ще получите това:



    Здравей свят

    Този втори пример работи, но има много неочаквани странични ефекти. Правилата за дефиниране на JavaScript променливи и обхват са в най-добрия случай объркващи. В първия случай JSHint ще докладва следното:

    test.js: ред 3, колона 17, "myvar" не е дефиниран.

    Във втория случай той ще докладва това:



    test.js: ред 2, колона 5, "myVar" не е дефиниран.
    test.js: ред 3, колона 17, "myVar" не е дефиниран.

    Първият пример ще ви помогне да избегнете грешка по време на изпълнение. Не е нужно да тествате приложението си - JSHint ще намери грешката вместо вас. Вторият пример е по-лош, тъй като няма да откриете грешка в резултат на тестване.


    Проблемът във втория пример е коварно фин и сложен. Променливата myVar вече изчезна от своя обхват и се премести нагоре в глобалния обхват. Това означава, че той ще съществува и ще има стойността Hello, World дори след като тестовата функция е стартирана. Това се нарича глобално замърсяване.


    Променливата myVar ще съществува за всяка друга функция, която се изпълнява след тестовата функция. Изпълнете следния код, след като изпълните тестовата функция:



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

    Все пак ще получите Здравей, свят. Променливата myVar ще виси във вашия код като шаблон, което води до сложни грешки, които ще търсите цяла нощ преди пускането, всичко това, защото сте забравили да напишете var.


    Този запис премина през услугата Full-Text RSS - ако това е вашето съдържание и вие го "четете на някой друг" сайт, моля, прочетете ЧЗВ на http://ift.tt/jcXqJW.


    Не всеки ред от моя код е перфектен от първия път. Е, в някои случаи ... Понякога ... Добре - почти никога. Истината е, че прекарвам значително повече време в коригиране на собствените си глупави грешки, отколкото бих искал. Ето защо използвам статични анализатори в почти всеки JavaScript файл, който пиша.

    Статичните анализатори разглеждат вашия код и намират грешки в него, преди да го стартирате. Те извършват прости проверки, като налагане на проверка на синтаксиса (например табулатори вместо интервали) и по-глобални проверки, като проверка дали функциите не са прекалено сложни. Статичните анализатори също търсят грешки, които не могат да бъдат открити по време на тестване, например == вместо ===.

    В големи проекти и когато работите в големи екипи, можете да използвате малко помощ при намирането на такива „прости“ грешки, които всъщност се оказват не толкова прости, колкото изглеждат.

    JSLint, JSHint и Closure Compiler

    Има три основни опции за статични анализатори за JavaScript: JSLint, JSHint и Closure Compiler.

    JSLint беше първият статичен анализатор за JavaScript. Може да се стартира на официалния сайт или да се използва една от добавките, които могат да се изпълняват на локални файлове. JSLint открива много важни грешки, но е много труден. Ето един отличен пример:

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

    JSLint показва две грешки в този код:

    Неочаквано "++". Преместете декларациите "var" в горната част на функцията.

    Първият проблем е дефинирането на променливата i в условията на цикъла. JSLint също не приема оператора ++ в края на дефиницията на цикъла. Той иска кодът да изглежда така:

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

    Оценявам създателите на JSLint, но за мен това е излишно. Оказа се трудно и за Антон Ковалев, така че той създаде JSHint.

    JSHint работи по същия начин като JSLint, но е написан в допълнение към Node.js и следователно е по-гъвкав. JSHint включва голям брой опции, които ви позволяват да извършвате персонализирани проверки, като напишете свой собствен генератор на отчети.
    Можете да стартирате JSHint от уебсайта, но в повечето случаи е по-добре да инсталирате JSHint като локален инструмент за команден ред с помощта на Node.js. След като инсталирате JSHint, можете да го стартирате във вашите файлове с команда като тази:

    Jshint test.js

    JSHint също така включва плъгини за популярни текстови редактори, така че можете да го стартирате, докато пишете своя код.

    ЗАТВАРЯВАЩ КОМПИЛАТОР

    Closure Compiler на Google е напълно различен вид програма. Както подсказва името му, това е не само тестова програма, но и компилатор. Написан е на Java и базиран на анализатора Rhino на Mozilla. Closure Compiler включва прост режим за извършване на основна проверка на кода и по-сложни режими за извършване на допълнителна проверка и налагане на специфични дефиниции на изглед.

    Компилаторът за затваряне отчита грешки в JavaScript кода, но също така генерира минимизирани версии на JavaScript. Компилаторът премахва интервалите, коментарите и неизползваните променливи и опростява дългите изрази, за да запази скрипта възможно най-компактен.

    Google направи много основна версия на компилатора достъпна в мрежата, но най-вероятно ще искате да изтеглите Closure Compiler и да го стартирате локално.

    Closure Compiler, след проверка на кода, извежда списък с файлове в един минимизиран файл. Така че можете да го стартирате, като изтеглите файла compiler.jar.

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

    Избор на правилната програма за проверка

    В моите проекти комбинирам Closure Compiler и JSHint. Closure Compiler прави минимизиране и основно валидиране, докато JSHint прави по-сложен анализ на кода. Тези две програми работят чудесно заедно и всяка от тях покрива области, които другата не може. Освен това мога да използвам разширението JSHint, за да пиша персонализирани валидатори. Една обща програма, която написах, тества определени функции, които не са ми необходими, като например извикване на функции, които не трябва да са в моя проект.

    След като разгледахме няколко програми за проверка, нека разбием някои от лошия код. Всеки от тези шест примера е код, който не си струва да се пише и ситуации, в които валидаторите на код могат да ви спасят.

    Тази статия използва JSHint за повечето примери, но Closure Compiler обикновено генерира подобни предупреждения.

    == или ===?

    JavaScript е динамично въведен език. Не е нужно да дефинирате типове, докато пишете кода си и те съществуват при стартиране.

    JavaScript предлага два оператора за сравнение за манипулиране на такива динамични типове: == и ===. Нека да разгледаме това с пример.

    Var n = 123; var s = "123"; if (n == s) (предупреждение („Променливите са равни“);) if (n === s) (предупреждение („Променливите са идентични“);)

    Оператор за сравнение == са остатъците от езика C, в който има своите корени JavaScript. Използването му почти винаги е грешка: сравняването на стойности отделно от типове рядко е нещо, което разработчикът всъщност иска да направи. Всъщност числото "сто двадесет и три" е различно от низа "едно две три". Тези оператори са лесни за правописна грешка и дори по-лесно за грешно разчитане. Проверете този код с JSHint и ще получите това:

    Test.js: ред 9, колона 12, очаквано "===" и вместо това видях "==".

    Недефинирани променливи и късни дефиниции

    Нека започнем с малко прост код:

    Функционален тест () (var myVar = "Здравей, свят"; console.log (myvar);)

    Виждате ли грешката? Правя тази грешка всеки път. Изпълнете този код и получавате грешката:

    ReferenceError: myvar не е дефиниран

    Нека направим проблема малко по-сложен:

    Тест на функциите () (myVar = "Здравей, свят"; console.log (myVar);)

    Изпълнете този код и ще получите това:

    Здравей свят

    Този втори пример работи, но има много неочаквани странични ефекти. Правилата за дефиниране на JavaScript променливи и обхват са в най-добрия случай объркващи. В първия случай JSHint ще докладва следното:

    Test.js: ред 3, колона 17, "myvar" не е дефиниран.

    Във втория случай той ще докладва това:

    Test.js: ред 2, колона 5, „myVar“ не е дефиниран. test.js: ред 3, колона 17, "myVar" не е дефиниран.

    Първият пример ще ви помогне да избегнете грешка по време на изпълнение. Не е нужно да тествате приложението си - JSHint ще намери грешката вместо вас. Вторият пример е по-лош, тъй като няма да откриете грешка в резултат на тестване.

    Проблемът във втория пример е коварно фин и сложен. Променливата myVar вече изчезна от своя обхват и се премести нагоре в глобалния обхват. Това означава, че той ще съществува и ще има стойността Hello, World дори след като тестовата функция е стартирана. Това се нарича глобално замърсяване.

    Променливата myVar ще съществува за всяка друга функция, която се изпълнява след тестовата функция. Изпълнете следния код, след като изпълните тестовата функция:

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

    Все пак ще получите Здравей, свят. Променливата myVar ще виси във вашия код като шаблон, което води до сложни грешки, които ще търсите цяла нощ преди пускането, всичко това, защото сте забравили да напишете var.