Що робить провідна крапка з комою в бібліотеках JavaScript?


156

У кількох бібліотеках JavaScript я побачив цю нотацію на самому початку:

/**
 * Library XYZ
 */
;(function () {
  // ... and so on

Хоча мені прекрасно подобається синтаксис "негайно виконана функція"

(function(){...})()

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

Чи має він якийсь інший функціонал?


Відповіді:


140

Це дозволяє безпечно об'єднати кілька файлів JavaScript в один, щоб швидше їх обслуговувати як один HTTP-запит.


16
Але не було б необхідності, якби всі файли були закодовані правильно, чи не так?
Болдевін

8
Ні: у вашому прикладі ви отримаєте (function(){...})()(function(){...})().
Аарон Дігулла

8
Це я мав на увазі «правильно закодовано», що кожна бібліотека закінчується правильною кількістю крапки з комою ...
Boldewyn

6
Так, Болдевін, але це просто не так.
Mathias Bynens

13
Два неправильно закодовані файли не підходять лише тим, що третій файл містить це брудне виправлення. Чому конкатенатор не може в результаті додавати додаткові крапки з комою між файлами?
Давид Хорват

30

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

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

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


Навіщо також закінчувати вирази крапками з комою, якщо ви використовуєте захисні крапки з комою? Або ви ризикуєте покластися на крапки з комою, що знаходяться в кінці кожного рядка, або ви використовуєте захисні крапки з комою. Якщо робити те і інше, люди неправильно роблять висновок про те, що є причина робити те і інше. Порада використовувати оборонні крапки з комою добре; рада також замінити кожен екземпляр "\n"з ";\n"не має ніякого сенсу.
Володимир Корнеа

4
@VladimirKornea: тому що ти не завжди використовуєш лише власні бібліотеки :)
jvenema

@jvenema Я не знаю, чому ти вважаєш, що це має значення.
Володимир Корнеа

6
Тому що ви не можете покладатися на чужий код, керуючись своїми умовами. Кодуйте оборонно і тоді вам не доведеться.
jvenema

1
@VladimirKornea Ви можете вважати це також оборонним, якщо хочете - воно захищає від чужого коду, який не завжди починається з оборонних крапків.
Натан Хінчі

26

Загалом, якщо вислів починається з (, [, /, +, або -, є ймовірність, що його можна було б трактувати як продовження заяви раніше. Заяви, що починаються з /, +, і - є досить рідкісними на практиці , але заяви, що починаються з (і [зовсім не рідкість, принаймні, в деяких стилях програмування JavaScript. Деякі програмісти люблять ставити захисну крапку з комою на початку будь-якого такого виразу, щоб вона продовжувала працювати правильно, навіть якщо заява перед тим, як її змінити та видалити попередньо закінчену крапку з комою:

var x = 0 // Semicolon omitted here
;[x,x+1,x+2].forEach(console.log) // Defensive ; keeps this statement separate

Джерело:

JavaScript: Постійний посібник, 6-е видання


9

Це згадується як провідна крапка з комою.

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


7

Однорядкова відповідь - безпечно об'єднати кілька файлів JavaScript. Використання крапки з комою не викликає проблем.

Припустимо, у вас є кілька функцій:

IIFE 1

(function(){
  // The rest of the code
})(); // Note it is an IIFE

IIFE 2

(function(){
   // The rest of the code
})(); // Note it is also an IIFE

При конкатенації це може виглядати так:

(function(){})()(function(){})()

Але якщо перед функцією додати крапку з комою, вона виглядатиме так:

;(function(){})();(function(){})()

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

Приклад 2

Припустимо, у вас є файл JavaScript зі змінною:

var someVar = "myVar"

Ще один файл JavaScript з деякою функцією:

(function(){})()

Тепер при конкатенації це буде виглядати так

var someVar = "myVar"(function(){})() // It may give rise to an error

З напівкрапкою це буде виглядати так:

var someVar = "myVar";(function(){})()

4

Добре, коли ви мінімізуєте код JavaScript. Це запобігає несподіваним синтаксичним помилкам.


Як що? Чи має крапка з комою якесь значення для наступного коду чи це просто для гіпотетичного коду помилок, об'єднаного перед фактичною бібліотекою?
Болдевін

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

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