Як уникнути типових "динамічних мовних помилок"?


42

Нещодавно я висипав пару годин у JavaScript, тому що хотів отримати перевагу від масивної бази користувачів. При цьому я помітив закономірність, яку більшість людей приписують динамічним мовам. Ви швидко працюєте, але коли ваш код досягає певного розміру, ви витрачаєте багато часу на помилки типу, написання та рефакторингу. Помилки, від яких компілятор зазвичай не шкодував мене. І не потрібно шукати помилок у логіці, коли я щойно робив помилку в іншому модулі.

Враховуючи неймовірний наступний JavaScript та інші динамічно набрані мови, я вважаю, що в моєму підході щось не так. Або це лише ціна, яку ви повинні заплатити?

Коротше кажучи:

  • Як ви підходите до проекту JavaScript (або будь-якої іншої динамічної мови з цього питання) з ~ 2000 LOC?
  • Чи є інструменти, які не дозволяють мені зробити ці помилки? Я спробував потік Facebook та JSHint, які дещо допомагають, але не вловлюють помилки.

2
Хоча є способи пом'якшити витрати, там є витрати .
дкастро

29
Я б спробував написати вашу програму статично набраною мовою, яка компілюється в javascript, наприклад Typescript, Scala.js або Elm.
дкастро

6
звіти про тестування, тестування, більше тестування та покриття.
njzk2

7
~ 2000 LOC - невеликий проект. Він легко вписується в те, що динамічна мова робить легко і добре. Якщо ви боретеся з таким проектом розміру, у вас є більш принципова проблема зі своїми навичками програмування, ніж все, що стосується конкретних динамічних мов.
Джек Едлі

5
@JackAidley Не погоджується. ОП використовується для фокусування на проблемах високого рівня, а не того, чи правильно написано ідентифікатор. Це вміння програмування. Забезпечення правильності написання може здійснюватись середній клас та / або підтримка інструментів.
mucaho

Відповіді:


37

Зокрема, про JavaScript, ви можете використовувати TypeScript замість цього. Він пропонує деякі речі, про які ви маєте на увазі. Цитування веб-сайту:

Типи дозволяють розробникам JavaScript використовувати високопродуктивні засоби розробки та практики, такі як статична перевірка та рефакторинг коду під час розробки програм JavaScript.

І це просто суперсета JS, тобто частина вашого існуючого коду буде працювати з TS просто чудово:

TypeScript починається з того ж синтаксису та семантики, про які сьогодні знають мільйони розробників JavaScript. Використовуйте існуючий код JavaScript, включайте популярні бібліотеки JavaScript і дзвоніть TypeScript з JavaScript.


11
... а TypeScript - це по суті Ecmascript 6.
Роберт Харві

11
Е, ця цитата болить. Це просто показує, що Microsoft завжди була компанією зі статичними мовами, яка просто не розуміє динамічних мов. "Типи дозволяють… рефакторинг коду"? Дійсно? Чи усвідомлює PR-відділ Майкрософт, що рефакторинг коду як практика був винайдений у Smalltalk (динамічна мова) та існував ще до цього у Forth (мова без типу)? Що перший інструмент автоматизованого рефакторингу був частиною IDE Smalltalk, перш ніж статичні мови навіть мали IDE? Ці сучасні IDE Smalltalk мають інструменти рефакторингу, принаймні такі ж потужні, якщо не більше, ніж Java, C # та C ++? Давай
Йорг W Міттаг

5
TypeScript - це сама по собі чудова мова, чому вам потрібно намагатися і підштовхувати її до такої дурниці?
Йорг W Міттаг

29
@ Jörg Я не знаю достатньо про Smalltalk, але кожен, який я бачив, IDE для JavaScript або Python - це милі за те, що може зробити хороший IDE для Java або C #. Також є деякі речі, які просто неможливо зробити динамічною мовою (деякі із найпопулярніших рефакторинга): скажіть, у вас є публічна функція foo(x) { return x.bar;}чи щось подібне. Оскільки немає відомостей про тип і функція є загальнодоступною (отже, ви не можете знати всіх абонентів), вам неможливо зрозуміти, чи слід перейменовувати баз у baz, якщо ви перейменовуєте якийсь клас.
Во

10
Ця відповідь говорить про те, що рішення "динамічних мовних помилок" - це взагалі не використовувати динамічну мову.
bgusach

19

Є кілька підходів, які можуть допомогти:

Блок тестування

Пишіть одиничні тести, де це можливо. Одино покладатися на ручне тестування або виявлення помилок у дикій природі - це хіт-і-міс.

Використовуйте рамки

Замість того, щоб прокручувати свої власні та ризикувати введенням помилок, використовуйте встановлені рамки, де це можливо.

Віддавайте перевагу CSS / мовам високого рівня

Де ви можете передати функціональність CSS або будь-якій мові високого рівня, якою ви пишете.

Рефактор

Рефактор для зменшення кількості коду. Менше коду = менше місць, коли речі можуть піти не так.

Повторне використання

Використовуйте наявний код там, де можна. Навіть якщо код не відповідає точності, його можна краще скопіювати, вставити та змінити, а не писати щось заново.

ІДЕ

Сучасні IDE, як правило, мають принаймні деяку підтримку Javascript. Деякі текстові редактори також знають Javascript.


5
Хоча правда, Ваша порада в основному стосується кожної мови програмування і в основному має на меті виправлення логічних помилок, а не тих, що виникають у динамічних мовах.
edmz

1
"Ваша порада в основному стосується кожної мови програмування" . Дуже вірно - подібним чином, як переходити через передачі від хобі-проектів до повноцінного корпоративного рішення, що вимагає збільшення кількості обмежень, аналогічно - чим більше написаного Javascript, тим більше дисципліни потрібно, якщо колеса не збираються швидко відриватися. Ерік Ліпперт це дуже добре описує.
Роббі Ді

4
"Віддавайте перевагу мовам CSS / високого рівня" - я не дуже розумію, що означає цей біт стосовно JavaScript: ви говорите про переміщення елементів (наприклад, анімації, можливо?) У таблиці стилів, а не в код JS? Як CSS ставиться до мов високого рівня?
черговий день

@anotherdave Багато чого з того, що раніше було міцно доменом Javascript, можна досягти в CSS3. Деякі функціональні можливості також можуть бути перенесені на мову вищого рівня, яка підлягає більш жорсткому контролю.
Роббі Ді

4
@anotherdave Багато з того, що люди намагаються зробити з JavaScript, є стороннім і недоречним. Бібліотеки, які надають стандартні мовні інструменти, рамки, що надають стандартним HTML-елементам трохи більше, код, що реплікує основні функціональні можливості, наприклад, якорі, емуляція MVC, стилізація, повторне втілення DOM, абстракція AJAX, візуалізація тривіальних об'єктів (повторне виконання SVG), функції поліфілінгу, які не користь користувачеві ... Ви повинні мінімізувати суму JS, яку ви пишете. Якщо ви можете зробити це без JS, зробіть це без JS.
bjb568

2

Один з інструментів, про який ще не було сказано, - це простий текстовий пошук у текстовому файлі чи проект .

Це звучить просто, але коли ви включаєте деякі регулярні вирази, ви можете зробити основні для розширеної фільтрації, наприклад, пошук слів, що знаходяться в документації або вихідному коді.

Це був ефективний інструмент для мене (крім статичних аналізаторів), і, враховуючи, що ваш проект розміром 2 к LOC, який, на мою думку, не особливо великий, повинен сподіватися творити чудеса.


2
grepпроходить довгий шлях. Якщо ви не робите занадто дивні динамічні речі, це робить трюк. Однак, вам здається, що ви звикли до IDE для мов статичного типу.
bgusach

1

Зараз я переробляю кілька тисяч рядків коду для великого проекту AngularJS. Однією з найбільших проблем є з'ясування точного контракту певної функції. Я іноді закінчував читання документації API, оскільки елементи необробленої відповіді API були призначені змінним, які пройшли через 6 шарів коду, перш ніж змінюватись і поверталися через ще 6 шарів коду.

Перша моя порада - проектувати за контрактом . Візьміть конкретний вклад, виробляйте конкретний вихід, уникайте побічних ефектів і документуйте ці очікування за допомогою TypeScript або принаймні JSDoc.

Моя друга порада - здійснити якомога більше перевірок. Ми дотримуємось стандарту AirBnB і використовуємо eslint на всій нашій кодовій базі. Гачки для фіксації підтверджують, що ми завжди дотримуємось стандарту. У нас, природно, є батарея блоку приладів і приймальні тести, і всі зобов'язання повинні бути переглянуті експертом.

Перехід від текстового редактора (Sublime Text) до власного IDE (WebStorm) також значно полегшив роботу з кодом взагалі. WebStorm використовуватиме JSDoc, щоб давати підказки про очікувані типи параметрів та підвищувати помилки, якщо ви подаєте неправильний тип або використовуєте повернене значення неправильним чином.

В JavaScript нові функції, такі як символи та геттер / сеттери, можуть допомогти забезпечити певний рівень якості шляхом додавання тверджень до присвоєння змінної (наприклад, переконайтесь, що ціле число знаходиться в межах діапазону або що об'єкт даних має певні атрибути).

На жаль, я не думаю, що існує справжнє рішення для запобігання динамічних мовних помилок. Це лише ряд заходів, які можуть допомогти зменшити їх частоту.


0

Моя відповідь на питання "Як ви підходите до проекту JavaScript (або будь-якої іншої динамічної мови з цього питання) з ~ 2000 LOC?"

Я розробляю програми формату PDF. Я підходжу до свого проекту розробки програмного забезпечення JavaScript (незалежно від розміру вихідного коду), використовуючи чисті елементи та примітки Петрі. Метод не пов'язаний з будь-якою конкретною технологією мови програмування. Таким чином, він може використовуватися для інших "мов програмування".

Я створюю схему логіки програми. Щоб діаграма не була захаращеною, я додаю більшість своїх анотацій до форми, яку я використовую з діаграмою. Записи у формі включають посилання на властивості або функції. Потім виписую вихідний код на основі інформації на схемі та записів у формі. Метод є систематичним, оскільки кожен написаний вихідний код безпосередньо відображається із діаграми та записів у формі. Вихідний код можна легко перевірити, оскільки я також дотримуюсь умов іменування та кодування, коли пишу код.

Наприклад, я обрав умову про те, що всі функції є прототипами. Якщо продуктивність стає проблемою, то її можна покращити, оголосивши функції в конструкторі. Для деяких властивостей я використовую масиви. Знову ж, якщо продуктивність стає проблемою, то її можна покращити, використовуючи прямі посилання.

Я також використовую eval. Це може значно зменшити розмір вихідного коду. Через проблеми з продуктивністю я використовую eval на початку або ініціалізацію частини моєї програми; Я ніколи не використовую його в "логіці виконання" - це ще одна умова кодування, яку я дотримуюся.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.