Декларация-вызов в JS
Сегодня на первой части семинара Ильи Кантора по JS присутствовал (к сожалению, на второй части не получится, буду в Москве это время). Немного поговорили о частом паттерне «объявили функцию и тут же вызвали». Используется этот приём (если кто не знаком с ДжаваСкриптом) для изоляции — в этом языке функции единственное, что может создавать зоны видимости.
Я вскользь затронул свой любимый способ — описание функции и вызов через восклицательный знак или тильду, вместо оборачивания скобками. Вообще, в JS непосредственный вызов функции сразу по месту определения возможен, только если декларация находится в контексте выражения. Для этого и нужны традиционные скобки:
(function () {
// скобки вокруг функции говорят интерпретатору, что это выражение
})();Вообще говоря, можно использовать любые средства, чтобы декларация стала частью выражения. Например, можно
Использование тильды или восклицательного знака гораздо лучше скобок по трём причинам:
!function () {
//
}();И,
var a = 5
(function() {})()Причём ошибку, которую найти иногда довольно трудно, да и сообщение о ней не самое дружественное: «TypeError: 5 is not a function». На самом деле, тут пропущена точка с запятой. Интерпретатор считает, что ему встретились две части выражения, между которыми пропущен
Обычно для этого добавляют точку с запятой сразу перед такими блоками.
Но если использовать унарный оператор, то этой проблемы просто нет (поэтому, на самом деле, мы экономим два байта, ещё и точка с запятой не обязательна):
var a = 5
!function () {}()Тут интерпретатор, встретив унарный оператор, понимает, что предыдущее выражение закончилось и началась новая конструкция.
Комментарии 33
Но мне кажется использование таких приемов и не расставления точек с запятых противоречит общепринятым код стандартам. Разве нет?
Вот тут еще несколько граблей, на которые можно наступить, если не ставить точки с запятой: http://lucumr.pocoo.org/2011/2/6/automatic … insertion/
При аккуратном программировании лучше использовать точку с запятой. Жизнь сложнее. Иногда люди её пропускают.
Тысячи их. Смысл не в том, чтобы не ставить точку с запятой и этим экономить байт, а в том, чтобы предотвращать появление ошибки такой простой штукой. Это как в Си рекомендуется в сравнении ставить константу слева, чтобы найти ошибку сразу, если вдруг забудешь одно «равно» поставить.
В файле. Причём здесьJS-движки?
PS: почему я не могу ответить лично автору? ;) В списке значатся варианты «всем» и трое отписавшихся.
Либо так, либо две статьи будут на последней странице.
А зачем? Я и так всё читаю.
Может «может», а не «могут»?:-)
Да якак-то не слежу :) Почитаю, спасибо!
Ограничивать видимость можно еще такой модной штукой как let
https://developer.mozilla.org/en/New_in_Ja … _statement
Комментарий для Евгения Степанищева:
Это дурацкая рекомендация, выворачивающая мозг. «Если 5 равно длине» — совершенный дурдом. Когда комфортная читаемость кода приносится в жертву надуманной проблеме — это зло. А надуманная потому, что на выражение «if (i=5)» компилятор (например, gcc) выдает предупреждение. Да даже если бы и не выдавал, так всё равно писать нельзя. Код должен быть логичным. В нем должно быть ясно видно то, что он делает, и чтобы его можно было читать гладко, а не спотыкаясь.
И в самом посте тоже извращения. Сэкономили один байт, поставив семантически бессмысленнейшую конструкцию. !function. Что и зачем здесь отрицается? Это форма без содержания. Это от мизантропии? «Да чтоб у вас крышу сорвало, если надумаете читать моё произведение!»
Особый шик ситуации в том, что это уродование кода оправдывается тем, что оно как бы решает другую проблему кода: отсутствие знаков препинания. «Я накосячил, забив на точки с запятой, но это может вызвать проблемы, поэтому нужно накосячить еще больше — ставить восклицательные знаки там, где они вообще не уперлись.»
Комментарий дляmaxim-zotov:
почему?
Согласен с вами, очень разумно всё говорите.
Комментарий дляmaxim-zotov:
Вы ужерунды-то не говорите. Если вы так читаете это конструкцию, то вы делаете ошибку. Она означает «если пять и длина равны между собой». Тем более, что в ПХП и многих других языках с автоматическим приведением типов она работает именно так.
А оборачивание скобками — форма с содержанием что ли? Пока не ввели «let» приходится изолироватьфункцией-выражением, выражение можно строить любым способом. Не нравится вам восклицательный знак, используйте тильду что ли.
Код должен быть читаемым, а программист должен хорошо знать язык и основные его «хаки».
Комментарий для Евгения Степанищева:
У скобок только структурирующая функция, поэтому они смотрятся не так дико. Они не выполняют никакого модифицирующего действия. Тильда или восклицательный знак — абсолютно без разницы, какое именно бессмысленное отрицание применяется к выражению.
Евгений, я думаю, что следует дополнить, может для кого и не очевидно, что такая функция будет возвращать только приведенное к булеву типу (и инвертированное) значение.
Т. е. в данном случае (из пустой функции), просто вернется «!undefined», т. е. true
Комментарий дляmaxim-zotov:
Выполняют, конечно. Они переключают контекст. Если вы имеете ввиду, что скобки смотрятся более логично, возможно, но только профессионалу должно быть всё равно, что переключает контекст, а новичку непонятны оба выражения.
Но я за то выражение, которое страхует от такой частой ошибки как отсутствующая точка с запятой.
Комментарий для Yehat:
Если вы хотьчто-то знаете о прогрессе стандарта, то видите, наверное, что он становится похожим скорее на Пайтон, а не на Перл.
Опытный разработчик на таких вещах не спотыкается, он видит за ним смысл. Просто найдите
Кстати,сейчас мир js разбился на два лагеря — сторонники точек с запятыми и противники. В зависимости от того, кто из них победит и будет в дальнейшем определяться стандарт языка.
Противникам точек с запятыми приходится, кстати использовать особенности языка и различные хаки, чтобы у них всё работало и не слипалось при минимизации, а сторонникам приходится ставить много точек с запятыми :)
Я — «за», кстати, за точки с запятой.
Комментарий дляmaxim-zotov:
Я, конечно, могу понять для чего это делается — чтобы случайно пропустив знак равенства нарваться на ошибку компилятора, но даже при этом я в этом вопросе разделяю твой взгляд. Всегда когда встречаю «if(константа = переменная» возникает небольшое чувство отвращения. Всегда ведь логически — по той логике по которой работает мозг — последующее исполнение зависит именно от значения переменной, поэтому с неё было бы логично и начать.
Комментарий для Евгения Степанищева:
Опять офф:
Последнее мне кажется логичнее.
А сейчас — могу (ибо автор есть в числе отписавшихся, полагаю). Это не для автора, это для других ;)
Комментарий для SiMM:
Совершенно не логичнее. Большинство читают последнюю страницу, им гораздо удобнее ничего не листать.
Я подумаю на эту тему :)
Комментарий для Евгения Степанищева:
Есть статистика? Не знаю, как большинство (нет статистики), но я чаще перелистываю назад, а уж до последней страницы времён динозавров доберусь врядли.
Есть.