!function () {}();
javascript
function
Себастьян Отто
источник
источник
Ответы:
Синтаксис JavaScript 101. Вот объявление функции :
Обратите внимание, что нет точки с запятой: это просто объявление функции . Вам потребуется вызов
foo()
, чтобы фактически запустить функцию.Теперь, когда мы добавляем, казалось бы, безобидный восклицательный знак:
!function foo() {}
он превращается в выражение . Теперь это выражение функции .!
В одиночку не вызывает функцию, конечно, но теперь мы можем поставить()
в конце:!function foo() {}()
который имеет более высокий приоритет , чем!
и мгновенно вызывает функцию.Так что автор делает сохранение байта на выражение функции; более читабельный способ написать это будет так:
Наконец,
!
возвращает выражение true. Это происходит потому , что по умолчанию все IIFE возвратundefined
, который оставляет нам!undefined
чтоtrue
. Не особенно полезно.источник
!
возвращает логическое значение, мы все это знаем, но вы замечаете, что он также преобразует оператор объявления функции в выражение функции, чтобы можно было немедленно вызывать функцию, не заключая ее в скобки. Не очевидно, а ясно намерение кодера.var foo =
неоднозначность выражений / выражений, и вы можете просто написатьvar foo = function(bar){}("baz");
и т. Д.Функция:
ничего не возвращает (или не определено).
Иногда мы хотим вызвать функцию прямо при ее создании. Вы можете попробовать это:
но это приводит к
SyntaxError
.Использование
!
оператора перед функцией вызывает его как выражение, поэтому мы можем вызвать его:Это также возвратит логическое значение, противоположное возвращаемому значению функции, в данном случае
true
, потому что!undefined
естьtrue
. Если вы хотите, чтобы фактическое возвращаемое значение было результатом вызова, попробуйте сделать это следующим образом:источник
!
, чтобы превратить объявление функции в выражение функции, вот и все.!function
синтаксисЕсть хорошая точка для использования
!
для вызова функций, отмеченная в руководстве по airbnb JavaScriptВообще идея использовать эту технику для отдельных файлов (также называемых модулями), которые впоследствии объединяются. Предостережение заключается в том, что файлы должны объединяться инструментами, которые помещают новый файл в новую строку (что в любом случае является обычным поведением для большинства инструментов concat). В этом случае использование
!
поможет избежать ошибок, если ранее объединенный модуль пропустил конечную точку с запятой, и все же это даст гибкость, чтобы расположить их в любом порядке, не беспокоясь.Будет работать так же, как
но сохраняет один символ и выглядит произвольно лучше.
И кстати , любой из
+
,-
,~
,void
операторы имеют тот же эффект, с точки зрения вызова функции, конечно , если вы должны использовать что - то , чтобы вернуться из этой функции они будут действовать по- другому.но если вы используете шаблоны IIFE для одного файла с разделением кода на один модуль и используете инструмент concat для оптимизации (что делает одну строку одним файлом), то построение
Будет выполнять безопасное выполнение кода, так же, как самый первый пример кода.
Этот вызовет ошибку, поскольку JavaScript ASI не сможет выполнить свою работу.
Одно замечание относительно унарных операторов, они будут выполнять аналогичную работу, но только в том случае, если они используются не в первом модуле. Поэтому они не так безопасны, если вы не имеете полного контроля над порядком объединения.
Это работает:
Это не:
источник
Возвращает, может ли оператор оценить как ложный. например:
Вы можете использовать его дважды, чтобы привести значение к логическому:
Итак, чтобы более прямо ответить на ваш вопрос:
Редактировать: имеет побочный эффект изменения объявления функции на выражение функции. Например, следующий код недопустим, поскольку он интерпретируется как объявление функции, в котором отсутствует требуемый идентификатор (или имя функции ):
источник
var myVar = !function(){ return false; }()
может опустить!
подобное,var myVar = function(){ return false; }()
и функция будет выполнена правильно, а возвращаемое значение останется нетронутым.true
с!0
иfalse
с!1
. Сохраняет 2 или 3 символа.Это просто, чтобы сохранить байт данных, когда мы делаем минификацию javascript.
рассмотрим ниже анонимную функцию
Чтобы сделать вышеуказанное как самопризывающуюся функцию, мы, как правило, изменим приведенный выше код как
Теперь мы добавили два дополнительных символа,
(,)
кроме добавления()
в конце функции, которая необходима для вызова функции. В процессе минификации мы обычно фокусируемся на уменьшении размера файла. Таким образом, мы можем также написать вышеупомянутую функцию какТем не менее, обе являются функциями, вызывающими себя, и мы также сохраняем байт. Вместо 2 символов
(,)
мы просто использовали один символ!
источник
! это логический оператор НЕ , это логический оператор, который будет инвертировать что-то в противоположность.
Хотя вы можете обойти скобки вызванной функции, используя BANG (!) Перед функцией, она все равно инвертирует возвращаемое значение, что может быть не тем, что вы хотели. Как и в случае IEFE, он возвращает неопределенное значение , которое при обращении становится логическим значением true.
источник
Восклицательный знак заставляет любую функцию всегда возвращать логическое значение.
Конечным значением является отрицание значения, возвращаемого функцией.
Пропуск
!
в приведенных выше примерах будет SyntaxError .Тем не менее, лучший способ достичь этого:
источник
!
изменяет способ, которым среда выполнения анализирует функцию. Это заставляет среду выполнения рассматривать функцию как выражение функции (а не как объявление). Это позволяет разработчику немедленно вызывать функцию с использованием()
синтаксиса.!
также будет применять себя (то есть отрицание) к результату вызова выражения функции.Это еще один способ написания IIFE (выражение, вызываемое немедленно).
Другой способ написания -
такой же как
источник
(function (args) {...})()
синтаксис и оставил эту!function
форму инструментам минимизации и запутывания.!
будет отрицать (напротив) все, что вы ожидаете в результате, т.е. если у вас естькогда вы звоните
boy
, ваш результат будетtrue
, но в тот момент,!
когда вы добавите при вызовеboy
, т. е.!boy
ваш результат будетfalse
. Который другими словами вы имеете в виду NotBoy , но на этот раз это в основном логический результат, либоtrue
илиfalse
.Это то же самое, что происходит с
!function () {}();
выражением: запуск толькоfunction () {}();
помечает вас как ошибку, но добавляет!
прямо передfunction () {}();
выражением, делает его противоположным тому,function () {}();
которое должно вернуть васtrue
. Пример можно увидеть ниже:источник