!function () {}();
!function () {}();
Відповіді:
Синтаксис JavaScript 101. Ось декларація функції :
function foo() {}
Зверніть увагу , що немає точки з коми: це просто функція декларації . Вам потрібна виклик foo()
, щоб фактично запустити функцію.
Тепер, коли ми додаємо, здавалося б, нешкідливий знак оклику: !function foo() {}
це перетворює це на вираз . Тепер це вираження функції .
!
У поодинці не викликає функцію, звичайно, але тепер ми можемо поставити ()
в кінці: !function foo() {}()
який має більш високий пріоритет , ніж !
та миттєво викликає функцію.
Отже, що робить автор - це збереження байта на вираз функції; більш читаним способом написання було б таке:
(function(){})();
Нарешті, !
робить вираз поверненням істинним. Це тому, що за замовчуванням все повернення IIFE undefined
, яке залишає нас з !undefined
якими є true
. Не особливо корисно.
!
повертається булевим, ми всі це знаємо, але головне, що ви робите, це те, що він також перетворює оператор декларації функції у вираз функції, щоб функцію можна було негайно викликати, не загортаючи її в дужки. Не очевидний, і чітко наміри кодера.
var foo =
порушує неоднозначність тверджень / виразів, і ви можете просто написати var foo = function(bar){}("baz");
тощо.
Функція:
function () {}
не повертає нічого (або невизначено).
Іноді ми хочемо викликати функцію правильно під час її створення. Можливо, ви б спробували спробувати це:
function () {}()
але це призводить до а SyntaxError
.
Використання !
оператора перед функцією спричиняє його трактування як вираз, тому ми можемо його назвати:
!function () {}()
Це також поверне булеву протилежність зворотному значенню функції, в цьому випадку true
, тому що !undefined
є true
. Якщо ви хочете, щоб фактичне значення повернення було результатом дзвінка, то спробуйте це зробити так:
(function () {})()
!
- перетворити декларацію функції на вираз функції, ось і все.
!function
синтаксис
Існує хороший момент використання !
для виклику функції, позначеного в посібнику JavaScript airbnb
Як правило, ідея використовувати цю техніку в окремих файлах (ака-модулях), які згодом об'єднуються. Застереження тут полягає в тому, що файли повинні бути об'єднані інструментами, які ставлять новий файл у новий рядок (що так чи інакше є звичайною поведінкою для більшості інструментів 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. наприклад:
!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 (){}()
І все одно, обидва є самостійними функціями, і ми також зберігаємо байт. Замість двох символів (,)
ми просто використали один символ!
! є логічним НЕ оператором, це бульний оператор, який переверне щось на протилежне.
Хоча ви можете обійти дужки викликаної функції, скориставшись функцією BANG (!) Перед функцією, вона все одно інвертуватиме повернення, яке може бути не тим, що ви хотіли. Як і у випадку з IEFE, він повертається невизначеним , що при переверненні стає булевою істиною.
Замість цього використовуйте дужки, що закриваються, і 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