!function () {}();
!function () {}();
Ответы:
Синтаксис JavaScript 101. Вот объявление функции :
function foo() {}
Обратите внимание, что нет точки с запятой: это просто объявление функции . Вам потребуется вызов foo()
, чтобы фактически запустить функцию.
Теперь, когда мы добавляем, казалось бы, безобидный восклицательный знак: !function foo() {}
он превращается в выражение . Теперь это выражение функции .
!
В одиночку не вызывает функцию, конечно, но теперь мы можем поставить ()
в конце: !function foo() {}()
который имеет более высокий приоритет , чем !
и мгновенно вызывает функцию.
Так что автор делает сохранение байта на выражение функции; более читабельный способ написать это будет так:
(function(){})();
Наконец, !
возвращает выражение true. Это происходит потому , что по умолчанию все IIFE возврат undefined
, который оставляет нам !undefined
что true
. Не особенно полезно.
!
возвращает логическое значение, мы все это знаем, но вы замечаете, что он также преобразует оператор объявления функции в выражение функции, чтобы можно было немедленно вызывать функцию, не заключая ее в скобки. Не очевидно, а ясно намерение кодера.
var foo =
неоднозначность выражений / выражений, и вы можете просто написать var foo = function(bar){}("baz");
и т. Д.
Функция:
function () {}
ничего не возвращает (или не определено).
Иногда мы хотим вызвать функцию прямо при ее создании. Вы можете попробовать это:
function () {}()
но это приводит к SyntaxError
.
Использование !
оператора перед функцией вызывает его как выражение, поэтому мы можем вызвать его:
!function () {}()
Это также возвратит логическое значение, противоположное возвращаемому значению функции, в данном случае true
, потому что !undefined
есть true
. Если вы хотите, чтобы фактическое возвращаемое значение было результатом вызова, попробуйте сделать это следующим образом:
(function () {})()
!
, чтобы превратить объявление функции в выражение функции, вот и все.
!function
синтаксис
Есть хорошая точка для использования !
для вызова функций, отмеченная в руководстве по airbnb JavaScript
Вообще идея использовать эту технику для отдельных файлов (также называемых модулями), которые впоследствии объединяются. Предостережение заключается в том, что файлы должны объединяться инструментами, которые помещают новый файл в новую строку (что в любом случае является обычным поведением для большинства инструментов concat). В этом случае использование !
поможет избежать ошибок, если ранее объединенный модуль пропустил конечную точку с запятой, и все же это даст гибкость, чтобы расположить их в любом порядке, не беспокоясь.
!function abc(){}();
!function bca(){}();
Будет работать так же, как
!function abc(){}();
(function bca(){})();
но сохраняет один символ и выглядит произвольно лучше.
И кстати , любой из +
, -
, ~
, void
операторы имеют тот же эффект, с точки зрения вызова функции, конечно , если вы должны использовать что - то , чтобы вернуться из этой функции они будут действовать по- другому.
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
но если вы используете шаблоны IIFE для одного файла с разделением кода на один модуль и используете инструмент concat для оптимизации (что делает одну строку одним файлом), то построение
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Будет выполнять безопасное выполнение кода, так же, как самый первый пример кода.
Этот вызовет ошибку, поскольку JavaScript ASI не сможет выполнить свою работу.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Одно замечание относительно унарных операторов, они будут выполнять аналогичную работу, но только в том случае, если они используются не в первом модуле. Поэтому они не так безопасны, если вы не имеете полного контроля над порядком объединения.
Это работает:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Это не:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Возвращает, может ли оператор оценить как ложный. например:
!false // true
!true // false
!isValid() // is not valid
Вы можете использовать его дважды, чтобы привести значение к логическому:
!!1 // true
!!0 // false
Итак, чтобы более прямо ответить на ваш вопрос:
var myVar = !function(){ return false; }(); // myVar contains true
Редактировать: имеет побочный эффект изменения объявления функции на выражение функции. Например, следующий код недопустим, поскольку он интерпретируется как объявление функции, в котором отсутствует требуемый идентификатор (или имя функции ):
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
может опустить !
подобное, var myVar = function(){ return false; }()
и функция будет выполнена правильно, а возвращаемое значение останется нетронутым.
true
с !0
и false
с !1
. Сохраняет 2 или 3 символа.
Это просто, чтобы сохранить байт данных, когда мы делаем минификацию javascript.
рассмотрим ниже анонимную функцию
function (){}
Чтобы сделать вышеуказанное как самопризывающуюся функцию, мы, как правило, изменим приведенный выше код как
(function (){}())
Теперь мы добавили два дополнительных символа, (,)
кроме добавления ()
в конце функции, которая необходима для вызова функции. В процессе минификации мы обычно фокусируемся на уменьшении размера файла. Таким образом, мы можем также написать вышеупомянутую функцию как
!function (){}()
Тем не менее, обе являются функциями, вызывающими себя, и мы также сохраняем байт. Вместо 2 символов (,)
мы просто использовали один символ!
! это логический оператор НЕ , это логический оператор, который будет инвертировать что-то в противоположность.
Хотя вы можете обойти скобки вызванной функции, используя BANG (!) Перед функцией, она все равно инвертирует возвращаемое значение, что может быть не тем, что вы хотели. Как и в случае IEFE, он возвращает неопределенное значение , которое при обращении становится логическим значением true.
Вместо этого используйте закрывающую скобку и BANG ( ! ), Если это необходимо.
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
Другие операторы, которые работают ...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Комбинированные операторы ...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
Восклицательный знак заставляет любую функцию всегда возвращать логическое значение.
Конечным значением является отрицание значения, возвращаемого функцией.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Пропуск !
в приведенных выше примерах будет SyntaxError .
function bool() { return true; }() // SyntaxError
Тем не менее, лучший способ достичь этого:
(function bool() { return true; })() // true
!
изменяет способ, которым среда выполнения анализирует функцию. Это заставляет среду выполнения рассматривать функцию как выражение функции (а не как объявление). Это позволяет разработчику немедленно вызывать функцию с использованием ()
синтаксиса. !
также будет применять себя (то есть отрицание) к результату вызова выражения функции.
Это еще один способ написания IIFE (выражение, вызываемое немедленно).
Другой способ написания -
(function( args ) {})()
такой же как
!function ( args ) {}();
(function (args) {...})()
синтаксис и оставил эту !function
форму инструментам минимизации и запутывания.
!
будет отрицать (напротив) все, что вы ожидаете в результате, т.е. если у вас есть
var boy = true;
undefined
boy
true
!boy
false
когда вы звоните boy
, ваш результат будет true
, но в тот момент, !
когда вы добавите при вызове boy
, т. е. !boy
ваш результат будет false
. Который другими словами вы имеете в виду NotBoy , но на этот раз это в основном логический результат, либо true
или false
.
Это то же самое, что происходит с !function () {}();
выражением: запуск только function () {}();
помечает вас как ошибку, но добавляет !
прямо перед function () {}();
выражением, делает его противоположным тому, function () {}();
которое должно вернуть вас true
. Пример можно увидеть ниже:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true