!function () {}();
Что делает восклицательный знак перед функцией?
Ответ 1
Синтаксис JavaScript 101. Вот объявление функции:
function foo() {}
Обратите внимание, что нет точки с запятой: это просто функция Объявление. Вам понадобится вызов foo()
, чтобы запустить функцию.
Теперь, когда мы добавляем, казалось бы, безобидный восклицательный знак: !function foo() {}
он превращает его в выражение . Теперь это выражение функции.
Только !
не вызывает функцию, но мы можем теперь положить ()
в конец: !function foo() {}()
, который имеет более высокий приоритет, чем !
, и мгновенно вызывает функцию.
Итак, что делает автор, это сохранение байта на выражение функции; более читаемым способом написания будет следующее:
(function(){})();
Наконец, !
делает выражение return true. Это связано с тем, что по умолчанию все IIFE возвращают undefined
, что оставляет нас с !undefined
, который равен true
. Не особенно полезно.
Ответ 2
Функция:
function () {}
ничего не возвращает (или undefined).
Иногда мы хотим вызвать функцию справа, когда мы ее создаем. У вас может возникнуть соблазн попробовать следующее:
function () {}()
но это приводит к SyntaxError
.
Используя оператор !
до того, как функция заставит его обрабатываться как выражение, мы можем его назвать:
!function () {}()
Это также возвращает логическое значение, противоположное возвращаемому значению функции, в данном случае true
, потому что !undefined
- true
. Если вы хотите, чтобы фактическое возвращаемое значение являлось результатом вызова, попробуйте сделать это следующим образом:
(function () {})()
Ответ 3
Есть хороший момент для использования !
для вызова функций, отмеченных в руководстве по 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*/}()
Ответ 4
Возвращает, может ли оператор оценивать значение false. например:
!false // true
!true // false
!isValid() // is not valid
Вы можете использовать его дважды, чтобы принудительно использовать значение для boolean:
!!1 // true
!!0 // false
Итак, чтобы более точно ответить на ваш вопрос:
var myVar = !function(){ return false; }(); // myVar contains true
Изменить: У этого есть побочный эффект изменения объявления функции на выражение функции. Например. следующий код недействителен, поскольку он интерпретируется как объявление функции, в котором отсутствует требуемый идентификатор (или имя функции):
function () { return false; }(); // syntax error
Ответ 5
Восклицательный знак заставляет любую функцию всегда возвращать логическое значение. Конечным значением является отрицание значения, возвращаемого функцией.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Опуская !
в приведенных выше примерах будет SyntaxError.
function bool() { return true; }() // SyntaxError
Тем не менее, лучший способ достичь этого:
(function bool() { return true; })() // true
Ответ 6
! является логическим оператором НЕ, это логический оператор, который будет инвертировать что-то в свою противоположность.
Хотя вы можете обойти круглые скобки вызываемой функции с помощью BANG (!) перед функцией, она все равно инвертирует возврат, который может быть не таким, каким вы хотели. Как и в случае с IEFE, он возвращает undefined, который при инверсии становится логическим значением true.
Вместо этого используйте закрывающую скобку и BANG (!), если это необходимо.
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what 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
Ответ 7
Только для сохранения байта данных при миниатюризации javascript.
рассмотрим анонимную функцию ниже
function (){}
Чтобы сделать вышеприведенную функцию self invoking, мы обычно изменим приведенный выше код как
(function (){}())
Теперь мы добавили два дополнительных символа (,)
, кроме добавления ()
в конце функции, необходимой для вызова функции. В процессе минимизации мы обычно фокусируемся на уменьшении размера файла. Таким образом, мы можем также написать указанную выше функцию как
!function (){}()
Тем не менее, оба являются функциями self invoking, и мы также сохраняем байт. Вместо двух символов (,)
мы использовали только один символ !
Ответ 8
Еще один способ записи IIFE (непосредственное выражение функции).
Другой способ написания -
(function( args ) {})()
то же, что и
!function ( args ) {}();
Ответ 9
!
будет отрицать (наоборот) то, что вы ожидаете в результате, т.е. если у вас
var boy = true;
undefined
boy
true
!boy
false
когда вы вызываете boy
, ваш результат будет true
, но как только вы добавите !
при вызове boy
, i.e !boy
, ваш результат будет false
. Другими словами, вы имеете в виду NotBoy, но на этот раз это в основном логический результат: true
или false
.
То же самое, что происходит с выражением !function () {}();
, и только function () {}();
укажет вам ошибку, но добавит !
прямо перед вашим выражением function () {}();
, делает его противоположным function () {}();
> который должен вернуть вас true
. Пример можно увидеть ниже:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true
Ответ 10
Позвольте сохранить несколько других байтов!
(() => {})()
пример:
(() => {return "yeah"})()