Что делает функция или подразумевает? [Дубликат]

У меня была аналогичная проблема, и выяснилось, что вся проблема такого характера может быть решена следующим образом:

  1. дает всем вашим элементам стиль.
  2. дает выбранный вами item style.
  3. дает следующие элементы стиль с использованием + или ~.

, и таким образом вы сможете стилизовать свои текущие предыдущие элементы (все элементы переопределены текущими и следующими элементами) и ваши следующие элементы.

пример:

/* all items (will be styled as previous) */
li {
  color: blue;
}

/* the item i want to distinguish */
li.milk {
  color: red;
}

/* next items */
li ~ li  {
  color: green;
}


<ul>
  <li>Tea</li>
  <li class="milk">Milk</li>
  <li>Juice</li>
  <li>others</li>
</ul>

Надеюсь, что это кому-то поможет.

1057
задан Sebastian Otto 20 September 2010 в 22:21
поделиться

12 ответов

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

function foo() {}

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

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

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

Так что автор делает сохранение байта на выражение функции; более читаемым способом его написания было бы следующее:

(function(){})();

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

1745
ответ дан Carles Alcolea 18 August 2018 в 17:00
поделиться
  • 1
    +1. Это действительно лучший ответ здесь, и, к сожалению, вряд ли стоит его одобрить. Очевидно, что ! возвращает логическое значение, мы все это знаем, но самое важное, что вы делаете, это то, что он также преобразует оператор объявления функции в выражение функции, так что функция может быть немедленно вызвана без ее обертывания в круглых скобках. Не очевидна и явно цель кодера. – gilly3 28 July 2011 в 17:58
  • 2
    +1 Это единственный ответ, который на самом деле обращается к ПОЧЕМУ вы хотите сделать это, и почему он видит, что он используется больше, чем отрицание результата возврата, похоже, будет оправданным. Унарный оператор! (также ~, - и +) устраняет неоднозначность из объявления функции и позволяет parens в конце () вызывать функцию на месте. Это часто делается для создания локального пространства / пространства имен для переменных при написании модульного кода. – Tom Auger 28 September 2011 в 19:34
  • 3
    Другое преимущество - это! вызывает вставку в виде двоеточия, поэтому невозможно, чтобы эта версия была ошибочно конкатенацией с файлом, который не заканчивается символом:. Если у вас есть форма (), она будет считать ее вызовом функции того, что было определено в предыдущем файле. Совет шляпы моему сотруднику. – Jure Triglav 13 November 2012 в 22:31
  • 4
    @Carnix var foo = нарушает двусмысленность оператора / выражения, и вы можете просто написать var foo = function(bar){}("baz"); и т. Д. – Neil 8 October 2013 в 11:49
  • 5
    это уродливо видеть ... Длинный путь не слишком длинный, чтобы выбрать восклицательный знак. Этот способ мог бы сэкономить разработчику долю секунды и часы, чтобы понять других. – Pablo Ezequiel Leone 29 May 2014 в 18:00

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

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
3
ответ дан antzshrek 18 August 2018 в 17:00
поделиться

Функция:

function () {}

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

Иногда мы хотим вызвать функцию справа, когда мы ее создаем. У вас может возникнуть соблазн попробовать следующее:

function () {}()

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

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

!function () {}()

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

(function () {})()
328
ответ дан benekastah 18 August 2018 в 17:00
поделиться
  • 1
    кому это может понадобиться? – Andrey 20 September 2010 в 22:32
  • 2
    это только ответ, который объясняет случай в вопросе, браво! – Andrey 20 September 2010 в 22:36
  • 3
    Второй образец кода недействителен JavaScript. Цель ! - превратить объявление функции в выражение функции, вот и все. – Skilldrick 30 September 2011 в 09:28
  • 4
    @Andrey Загрузочный твиттер использует это во всех там плагинах javascript (jQuery). Добавление этого комментария только в том случае, если другие могут также иметь тот же вопрос. – Anmol Saraf 20 August 2012 в 19:07
  • 5
    d3.js также использует синтаксис !function – Kristian 31 March 2014 в 23:01

Существует хорошая точка для использования ! для вызова функции, отмеченного на 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*/}()
46
ответ дан JLRishe 18 August 2018 в 17:00
поделиться
  • 1
    Фактически, эти другие символы не имеют такого же эффекта. Да, они позволяют вам вызывать функцию, как описано, но они не идентичны. Рассмотрим: var foo =! Function (bar) {console.debug (bar); } (& Quot; летучая & Quot;); Независимо от того, какой из ваших символов вы ставите впереди, вы получаете «bat». в вашей консоли. Теперь добавьте console.debug («foo: & quot;, foo); - вы получаете очень разные результаты, основываясь на том, какой символ вы используете. ! заставляет возвращаемое значение, которое не всегда желательно. Я предпочитаю синтаксис ({}) () для ясности и точности. – Carnix 2 October 2013 в 21:28

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

Для последнего синтаксиса:

( function my_function() {} )()

Мы можем сделать что-то вроде:

(function add_them(a,b) { return a+b;} )(9,4)

Как одновременное определение функции и вызов.

Редактирование: теперь вы спросите, в чем польза '!' определение функции типа. Давайте рассмотрим следующее:

!function a_would_be_function() { alert("Do some junk but inside a function"); }()

вы хотели бы выполнить такую ​​функцию, как указано выше, но без '!' будет генерировать ошибку. Надеюсь, я понятен.

5
ответ дан jmorc 18 August 2018 в 17:00
поделиться

Его другой способ записи IIFE (непосредственное выражение функции).

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

(function( args ) {})()

, такой же, как

!function ( args ) {}();
2
ответ дан kamal 18 August 2018 в 17:00
поделиться
  • 1
    Ну, это не совсем то же самое; вторая форма отрицает результат вызова функции (и затем отбрасывает ее, потому что нет назначения значения). Я строго предпочитаю более явный синтаксис (function (args) {...})() и оставляю эту форму !function для инструментов минимизации и обфускации. – Tobias 16 October 2017 в 14:31

Он возвращает, может ли оператор оценивать значение 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
26
ответ дан RobG 18 August 2018 в 17:00
поделиться
  • 1
    Для ясности читателей, которые могут захотеть использовать присваивание с помощью сразу вызываемой функции, ваш код примера var myVar = !function(){ return false; }() может опустить ! как var myVar = function(){ return false; }(), и функция будет выполнена правильно, а возвращаемое значение будет не тронуто. – Mark Fox 11 March 2013 в 02:55
  • 2
    Чтобы быть понятным, вы можете использовать его один раз, чтобы принудительно использовать Boolean, потому что это оператор logical not . ! 0 = true, и! 1 = false. Для целей минимизации JavaScript вы хотите заменить true на !0 и false на !1. Он сохраняет 2 или 3 символа. – Triynko 26 July 2015 в 01:07

! является логическим оператором 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
3
ответ дан SoEzPz 18 August 2018 в 17:00
поделиться

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

(() => {})()

пример:

(() => {return "yeah"})()
0
ответ дан Zibri 18 August 2018 в 17:00
поделиться
3
ответ дан antzshrek 7 September 2018 в 01:45
поделиться
4
ответ дан antzshrek 30 October 2018 в 06:01
поделиться
0
ответ дан Mohamed Elshahawy 30 October 2018 в 06:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: