!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