Чим керування Python розривами рядків відрізняється від автоматичної крапки з комою JavaScript?


41

У Javascript є функція під назвою "Автоматичне вставлення крапки з комою", де в основному, якщо аналізатор зустрічає недійсний маркер, а останній маркер перед цим був розривом рядка, тоді аналізатор вставить крапку з комою, де знаходиться розрив рядків. Це дозволяє вам в основному писати весь код JavaScript без крапки з комою, але ви повинні знати про деякі крайні регістри, в основному, якщо у вас є ключове слово return, а потім значення, яке ви хочете повернути в новому рядку.

function test(){
    // This will return 'undefined', because return is a valid statement
    // and  "john" is a valid statement on its own.
    return 
          "john"
}

Через ці програми є десятки статей з назви "Автоматичне вставлення крапки з комою - це зло", "Завжди використовувати крапки з комою в Javascript" тощо.

Але в Python ніхто ніколи не використовує крапки з комою, і у нього є абсолютно однакові ґетчі.

def test():
    # This will return 'undefined', because return is a valid statement
    # and  "john" is a valid statement on its own.
    return 
    "john"

Працює точно так само, і все-таки ніхто не смертельно боїться поведінки пітонів.

Я думаю, що випадків, коли javascript веде себе погано, недостатньо, щоб ви могли легко їх уникнути. Повернення + значення в новому рядку? Чи справді люди роблять це багато?

Будь-які думки? Чи використовуєте ви крапки з комою в JavaScript та чому?


3
Це не працює точно так само. Вставка крапки з комою не обов'язково перебуває там, де новий рядок є обов'язково в JavaScript. Дивіться другий приклад на цій сторінці Вікіпедії . Точка з комою не вставляється там, де в цьому прикладі є нова лінія.
Рейд

1
Моя думка полягала не в тому, що використання крапки з комою та їх використання працювали абсолютно однаково, справа в тому, що регістри речей у javascript та python були однаковими. Звичайно, є кілька крайніх випадків, коли ви повинні знати, що відбувається. Краща стаття я прочитав на цю тему: inimino.org/~inimino/blog/javascript_semicolons
Ейнар Egilsson

4
Я розміщую крапки з комою в JavaScript з тієї ж причини, що використовую періоди у реченнях. Впевнений, що перекладач зазвичай може осмислити ваші висловлювання без них, але це просто погана форма.
JD Isaacks

3
Ви можете розглянути можливість написання дійсного python у своїх прикладах. Індикатор коментаря - це #не // //.
Аарон Дюфур

2
"явне завжди краще, ніж неявне"

Відповіді:


62

Причина в тому, що в Python нові рядки - це однозначний спосіб розділення рядків коду; це задум, і спосіб роботи це ретельно продумано. Як результат, код python ідеально читабельний та однозначний без спеціальних маркерів у кінці оператора (крім нового рядка).

Javascript, з іншого боку, був розроблений з C-подібним синтаксисом на увазі, де заяви завжди закінчуються крапкою з комою. Щоб зробити мову більш толерантною до помилок, вона намагається відгадати, куди слід займати крапки з комою, щоб зробити код правильним. Оскільки це було на зразок ретро вбудованого в C-подібний синтаксис, він не завжди працює так, як очікувалося (іноді інтерпретатор сценарію вважає неправильним), і може створити досить контр-інтуїтивний код. \

Або аргументувати терміни "явний краще, ніж неявний": У Python новий рядок вже повністю явний, тоді як у Javascript - неоднозначний, тому ви додаєте крапку з комою, щоб зробити це явним.


3
О, і ви можете помістити код в коментарі, використовуючи зворотні цитати.
tdammers

1
Хороший приклад випадку, коли автоматичне вставлення напівколонки в кінцевому підсумку робить несподівані речі, це такий: pastebin.com/aVeWGdya
HoLyVieR

5
У python правила досить прості: заяви закінчуються на переривках рядків, якщо не існує незакритого багаторядкового рядка ("" ", '' '), незакритого диктату ({}), незакритого списку ([]) або зворотної косої риски негайно до переривання рядків. У javascript правила значно складніші
Аарон Дюфур

5
Покриття 99% помилок - це хороший спосіб залишити після себе лише справді важкі помилки. Добре залишити їх позаду в python, оскільки існують прості правила, які охоплюють 100% проблем.
Аарон Дюфур

1
@Aaron: Ви забули "незакритий набір дужок (())". (Не суворо "незакритий кортеж", оскільки дужки використовуються не лише для кортежів.)
JAB

28

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

У Python розрив рядка завжди закінчується оператором, за винятком певних досить очевидних випадків, таких як вираз у дужці. JavaScript, з іншого боку, спробує розібрати якомога більше рядків, перш ніж закінчити оператор, що потенційно призведе до таких речей:

// Define a function and name it area.
area = function(r) {
    return r * r * 3.14159
}

// Fooled you! We're actually invoking it.
(14)

8
Тепер ось веселий поворот на цьому. Замінити 14 з чим - то начебто (a + 1) ? do_something() : do_something_else();і раптом, площа встановлюється на значення повернення do_something()або do_something_else()і ви залишаєтеся сильно збентежений.
Рейд

20

Я часто мінімізую свої JS-файли у виробничому режимі. Засоби, видалення коментарів та рядків.

Без використання крапки з комою, це порушить мій Javascript.


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

2
@Einar Egilsson компілятор закриття дійсно це робить.
серйозний

1
При рівності нового рядка така ж кількість байтів, як і крапка з комою. Ваш мінімізатор може позбавити всіх нових ліній, але тоді потрібно мати крапки з комою. Це рівномірний обмін.
Логан Бейлі

3
@ Логан: Це, звичайно, один байт новий рядок; звичайно;
Камерон

1
Звичайно, якби ми використовували Python замість Javascript, нам би довелося кодувати WAY менше, щоб зробити те саме, тому факт, що напівколонки використовують на кілька байт менше, ніж відступ, є суперечливим моментом.
BlueRaja - Danny Pflughoeft

5

Це не працює, як ви описуєте.

У Javascript є функція під назвою "Автоматичне вставлення крапки з комою", де в основному, якщо аналізатор зустрічає недійсний маркер, а останній маркер перед цим був розривом рядка, тоді аналізатор вставить крапку з комою, де знаходиться розрив рядків.

Це неправильно. Приклад:

return
  1 + 2;

1є ідеально допустимим маркером, але аналізатор все одно вставить крапку з комою безпосередньо після return.

Як бачите, навіть ви не можете точно сказати, де відбудеться крапка з комою.

Проблема з автоматичним введенням двояка:

  • Для одного, люди можуть залишити крапку з комою, де автоматичне вставлення не може визначити, що потрібно вставити.
  • Також крапку з комою можна вставити там, де це не призначено, як зазначено вище.

Звичайно, використання крапки з комою після кожного твердження допомагає лише при першому джерелі помилок.

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


1
Специфікація сценарію ECMA чітко визначає, у яких випадках буде вставлена ​​крапка з комою, тому ваш рядок "Ви не можете точно сказати, де відбудеться крапка з комою" є невірним. Проблема полягає в тому, що в деяких випадках це неінтуїтивно, а це важче навчати того, хто не розуміє, як це працює.
zzzzBov

1
@zzzzBov: Так, є точна специфікація, але чи дійсно хтось має на увазі всі випадки під час кодування? Ти впевнений? Програмісти ліниві, і це справедливо; вони не хочуть пам’ятати складне правило, коли це зробити набагато простіше. Тому вони намагаються обійти, пам'ятаючи про це.
Svante

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

1
@Svante: Але зворотний приклад показує нам, що ми мусимо знати ці правила все одно. Там ви використовували крапку з комою, але це не допомогло вам зробити те, що хотіли. Отже, враховуючи, що мова має цю особливість, ми маємо можливість (1) Писати крапки з комою та усвідомлювати правила, щоб ми зрозуміли, що буде (2) Не пишуть крапки з комою та усвідомлюють правила, щоб ми зрозуміли, що буде. Враховуючи цей вибір, я думаю, що я скоріше пропускаю крапки з комою
Ейнар Егілссон,

4

Я зазначу одну просту причину:

Javascript виглядає "свого роду java-ish" або "kinda C-ish". Звичайно, це динамічна мова, тому вона виглядає інакше ... але постарайтеся - є брекети. Мови із дужками зазвичай мають крапки з комою. Природні рефлекси підштовхуються і змушують ваш палець рухатися до крапки з крапкою з комою, перш ніж вдарити Enter.

Пітон, навпаки, навіть на перший погляд виглядає зовсім інакше. Отже, аналогія зі "стандартними нудними мовами" інтуїтивно формується, і коли людина переходить у режим "пітона", відсутність крапки з комою стає природною.


2

Існує ряд вагомих причин не використовувати вставку напівкрапки в JavaScript.

В першу чергу це тому, що введення напівколонок у визначені стандартом ECMAScript в деяких випадках неінтуїтивно. @Svante вказує на випадок, returnколи використання нового рядка спричинить проблеми.

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

Ще однією дуже вагомою причиною не використовувати вставку з двокрапкою - це контроль виходу. У багатьох випадках JavaScript запускається через мініфікатор перед використанням у виробництві. Деякі міні-майстри можуть працювати з автоматичними вставками напівколонки, але я не бачу причин розраховувати на те, що це працює ідеально

Крім того, для систем управління вмістом вбудований JavaScript може бути автоматично мінімізований, і я спостерігав ряд випадків, коли автоматичний міні-переглядач просто видаляє коментарі та обробляє пробіли з початку та в кінці кожного рядка.

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


Ах, вибачте, але щодо вашого третього абзацу я це згадую у своєму другому останньому реченні. :)
Svante

Так, проблема з інструментами є дійсною (хоча хороші мініфієри повинні впоратися з цим, наприклад компілятор закриття). Але, на мою думку, нам потрібно все-таки знати ці правила, щоб уникнути таких речей, як приклад "повернення". І коли я знаю правила, я можу також використовувати цю функцію, тим більше, що це робить код (IMO) більш читабельним.
Ейнар Егільссон

1

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


1

У Javascript ви можете написати програму, яка була б синтаксично правильною за відсутності автоматичної вставки з комою, і ASI перетворить цю програму в іншу синтаксично правильну програму (наприклад, перетворення коду, який повертає значення в код, який нічого не повертає). Немає аналогічного випадку у Python. У Python будь-який новий рядок, який може закінчити оператор , завершить оператором, якщо тільки це не уникнене зворотною косою рисою. Технічно я вважаю, що правила Javascript однаково детерміновані, але я не знаю, чи можна було б узагальнити правила Javascript для закінчення висловлювань в одному реченні.


1

У більшості випадків JavaScript ASI обробляє речі, як очікувалося. Один із прикладів ASI, можливо, не так, як ви очікували, такий:

var i = 0

(function() {
   // do something
})()

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

Для тих, хто не знайомий з ASI, це може бути дуже заплутано, коли ви стикаєтесь з подібними проблемами, тому я завжди рекомендую розробникам моєї команди використовувати крапки з комою.

(Вбік: я не використовую крапки з комою під час роботи над особистими / сторонніми проектами, бо знаю, що нікому більше не потрібно буде підтримувати код.)


1

Як і ви, я думаю, що це трохи параноїчно. Правила вставки крапки з комою добре визначені в JavaScript, як і в Python та CoffeeScript. Ніхто не засмічує Python або CoffeeScript з крапками з комою, тому чому JavaScript по-різному трактується?

Я думаю, що це надмірна реакція на жалюгідний стан типового коду JavaScript приблизно десять років тому. Це було збентеження. Ви не можете написати хороший код у JavaScript!

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

Чому JavaScript все ще трактується по-різному?

Є інерція. І не слід випускати з уваги те, що люди, які цінують чітко структурований код, часто віддають перевагу мовам С-стилю. Люди, які цінують неявно структурований код, часто переходять на мови, що не належать до С (наприклад, CoffeeScript).


0

Я використовую їх у Javascript суворо для послідовності. Якщо більшість рядків є

У Python є їх для кращих випадків, таких як декілька висловлювань в одному рядку, javascript має їх, і оскільки ви їх регулярно знайдете, я відповідаю нормі, де вони використовуються.

Я не можу знайти використання для декількох висловлювань в одному рядку, і тому не передбачаю використання крапки з комою.


Так, я зафіксував приклад Python. Але справа залишається в тому, що Python також має крапки з комою, ви можете розміщувати їх після кожного твердження (і, якщо у вас їх більше, ніж у кожному рядку), але люди не користуються ними.
Ейнар Егільссон

0

Якщо ви використовуєте щось як bundle-fu та менеджер активів для свого веб-додатка в рейках, то воно жахливо зламається, якщо воно не зустріне крапку з комою в кінці токена в JavaScript. Тож це є гарною практикою ставити її.


Ну, велика трійка - компресор YUI, компілятор закриття та UglifyJS - усі вставляють крапку з комою. Я не здивований, що у рубінового порту JSMin є проблеми.
Бенджамін Аткін

0

Я не можу згадати, яка саме версія IE, але є деякі випадки, коли IE буквально помилиться, якщо крапка з комою відсутня. IIRC - це коли ти маєш у глобальному масштабі щось на кшталт:

var myFunc = function() {
  ...
}

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

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