Что делает восклицательный знак перед функцией? - PullRequest
1152 голосов
/ 21 сентября 2010
!function () {}();

Ответы [ 10 ]

1949 голосов
/ 14 апреля 2011

Синтаксис JavaScript 101. Вот объявление функции :

function foo() {}

Обратите внимание, что точки с запятой нет: это просто функция объявление . Вам потребуется вызов, foo(), для фактического запуска функции.

Теперь, когда мы добавляем, казалось бы, безобидный восклицательный знак: !function foo() {} он превращает его в выражение . Теперь это выражение функции .

Конечно, только ! не вызывает функцию, но теперь мы можем поставить () в конце: !function foo() {}(), который имеет более высокий приоритет, чем ! и мгновенно вызывает функцию.

Итак, автор делает сохранение байта для выражения функции; более читабельный способ записи был бы такой:

(function(){})();

Наконец, ! заставляет выражение возвращать значение true. Это потому, что по умолчанию все IIFE возвращают undefined, что оставляет нам !undefined, что составляет true. Не особенно полезно.

352 голосов
/ 21 сентября 2010

Функция:

function () {}

ничего не возвращает (или не определена).

Иногда мы хотим вызвать функцию прямо при ее создании.Вы можете попробовать это:

function () {}()

, но это приводит к SyntaxError.

Использование оператора ! до того, как функция заставит его обрабатываться как выражение,поэтому мы можем вызвать его:

!function () {}()

Это также возвратит логическое значение, противоположное возвращаемому значению функции, в данном случае true, поскольку !undefined равно true.Если вы хотите, чтобы фактическое возвращаемое значение было результатом вызова, попробуйте сделать это следующим образом:

(function () {})()
55 голосов
/ 01 октября 2013

Есть смысл использовать ! для вызова функций, отмеченных в airbnb JavaScript guide

Обычно идея использовать эту технику для отдельных файлов (также называемых модулями), которые впоследствии объединяются. Предостережение заключается в том, что файлы должны объединяться инструментами, которые помещают новый файл в новую строку (что в любом случае является обычным поведением для большинства инструментов 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*/}()
28 голосов
/ 21 сентября 2010

Возвращает, может ли оператор иметь значение false.Например:

!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
6 голосов
/ 06 мая 2013

Восклицательный знак заставляет любую функцию всегда возвращать логическое значение. Конечным значением является отрицание значения, возвращаемого функцией.

!function bool() { return false; }() // true
!function bool() { return true; }() // false

Пропуск ! в приведенных выше примерах будет SyntaxError.

function bool() { return true; }() // SyntaxError

Однако лучший способ добиться этого был бы:

(function bool() { return true; })() // true
5 голосов
/ 05 сентября 2017

Это просто для сохранения байта данных при минимизации javascript.

рассмотрим нижеприведенную анонимную функцию

function (){}

Чтобы сделать вышеупомянутое самообращающимсяКак правило, мы будем изменять приведенный выше код как

(function (){}())

Теперь мы добавили два дополнительных символа (,), кроме добавления () в конце функции, которая необходима для вызова функции.В процессе минификации мы обычно фокусируемся на уменьшении размера файла.Таким образом, мы можем также написать вышеупомянутую функцию как

!function (){}()

Тем не менее, обе они являются функциями, вызывающими себя, и мы также сохраняем байт.Вместо 2 символов (,) мы просто использовали один символ !

5 голосов
/ 31 июля 2015

! - логический оператор NOT , это логический оператор, который будет инвертировать что-то в свою противоположность.

Несмотря на то, что вы можете обойти скобки вызванной функции, используя 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'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
2 голосов
/ 06 марта 2016

Это еще один способ записи IIFE (выражение, вызываемое немедленно).

Другой способ написания -

(function( args ) {})()

так же, как

!function ( args ) {}();
0 голосов
/ 23 июня 2018

Давайте сохраним несколько других байтов!

(() => {})()

пример:

(() => {return "yeah"})()
0 голосов
/ 13 января 2018

! будет отрицать (напротив) все, что вы ожидаете в результате, т.е. если у вас есть

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...