Что делает восклицательный знак перед функцией?

!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"})()