Что !! (не нет) оператор в JavaScript?

avatar
Hexagon Theory
24 апреля 2009 в 08:13
690420
40
3579

Я видел код, который, похоже, использует незнакомый мне оператор в виде двух восклицательных знаков, например: !!. Подскажите, пожалуйста, что делает этот оператор?

Контекст, в котором я это видел, был:

this.vertical = vertical !== undefined ? !!vertical : this.vertical;
Источник
Gus
15 февраля 2012 в 18:35
1137

Запомните это как "бах, бах, ты логический"

Phil H
12 февраля 2014 в 09:43
96

Для протокола: не делайте того, что там цитируется. Сделайте if(vertical !== undefined) this.vertical = Boolean(vertical); - это намного чище и понятнее, что происходит, не требует ненужных назначений, полностью стандартно и так же быстро (в текущих FF и Chrome) jsperf.com/boolean-conversion-speed.

jww
1 апреля 2014 в 12:11
0

«любой порядочный программист должен знать, что происходит ...» - иногда это помогает компилятору сгенерировать лучший код на компилируемых языках. Я знаю, что раньше Microsoft рекомендовала его при использовании кода C, потому что он генерировал лучший код. (Вероятно, это все еще рекомендуется, но я не могу найти ссылку на данный момент).

Vivek
16 июля 2014 в 07:21
90

!! не оператор. Это просто! оператор дважды.

matty
24 мая 2015 в 13:47
72

@schabluk, для записи, порядок операций является причиной того, что !!5/0 производит Infinity, а не true, как произведено Boolean(5/0). !!5/0 эквивалентен (!!5)/0 - он же true/0 - из-за того, что оператор ! имеет более высокий приоритет, чем оператор /. Если вы хотите логически преобразовать 5/0 с помощью двойного взрыва, вам нужно будет использовать !!(5/0).

user2808054
13 октября 2015 в 09:23
0

Проще говоря: !! vertical дает логическое значение, определяющее, определено ли 'vertical' или нет.

Karol Be
23 октября 2018 в 12:49
0

Для записи, Boolean (5/0) не то же самое, что !! 5/0 - schabluk 12 фев 2015 в 9:45 Да, потому что вы используете второй оператор без скобок. В любом другом случае они такие же логические (5/0), что и !! (5/0)

bytefish
14 декабря 2018 в 07:16
1

Просто объясните: !!value === Boolean(value)

Zachary Schuessler
19 июля 2019 в 17:39
10

@Gus Просто чтобы вы знали, я прочитал ваш комментарий waaaay еще в 2012 году. В течение 7 лет с тех пор я всегда с юмором говорил в своей голове: «Bang bang! Ты логический!» при инвертировании логического значения, и я всегда помнил, как это произошло в результате. Я решил посмотреть ваш комментарий сегодня и сообщить вам :-)

Gus
28 августа 2019 в 14:10
3

@ZacharySchuessler thx, я рад, что многим он понравился, и я даже видел, как это цитируется (и цитируется) на обучающих сайтах и ​​тому подобное, теперь это потрясающе :) Никогда не думал, что буду создавать такую ​​популярную мнемонику.

GregJF
29 апреля 2020 в 23:50
0

Фил Х. Кстати, в javascript вам не следует проверять переменную с помощью тернарного оператора (! == или ===). Просто используйте (variable == null). Проверка переменной с помощью тернарного оператора означает, что вам нужно будет проверить как undefined, так и null. В javascript (запрос OP) undefined! == null

GregJF
29 апреля 2020 в 23:58
0

если this.vertical == "good" и vertical == "other", то this.vertical будет изменено на логическое значение true !! Это не детерминировано. этот код просто изменит тип переменной, что приведет к неожиданным результатам

tatsu
9 октября 2020 в 08:29
0

@Gus Я люблю тебя, кухня, js!

Ответы (40)

avatar
stevehipwell
24 апреля 2009 в 08:18
3171

Преобразует Object в boolean. Если он был ложным (например, 0, null, undefined и т. Д.), Он будет false, иначе true.

!oObject  // inverted boolean
!!oObject // non inverted boolean so true boolean representation

Итак, !! не оператор, это просто оператор ! дважды.

Пример из реальной жизни «Тестовая версия IE»:

const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8); // returns true or false 

Если вы ⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns either an Array or null  

Но если вы ⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));  
// returns either true or false
Chuck
24 апреля 2009 в 17:14
139

Он преобразует небулево значение в инвертированное логическое значение (например,! 5 будет ложным, поскольку 5 не является ложным значением в JS), затем логическое инвертирование, чтобы вы получили исходное значение как логическое (так что !! 5 будет быть правдой).

Micah Snyder
24 апреля 2009 в 18:27
128

Проще всего это описать: Boolean (5) === !! 5; Тот же состав, меньше персонажей.

thetoolman
16 июля 2012 в 03:53
50

Это используется для преобразования истинных значений в логическое истинное, а ложные значения слишком логического ложного.

Yaroslav
22 октября 2012 в 12:38
0

Нашел эту неясную нотацию в php-коде Magento, подумал, что это могут быть два отдельных оператора not, но не был уверен. Этот ответ и некоторые другие комментарии прояснили мне ситуацию.

victorvartan
3 февраля 2013 в 12:24
15

@Micah Snyder: будьте осторожны, в JavaScript лучше использовать логические примитивы вместо создания объектов, которые объединяют логические значения с помощью new Boolean (). Вот пример, чтобы увидеть разницу: jsfiddle.net/eekbu

rds
26 марта 2014 в 19:43
7

Насколько мне известно, этот шаблон «взрыва» бесполезен внутри оператора if (… _; только в операторе return функции, которая должна возвращать логическое значение.

Azder
28 мая 2014 в 05:57
2

Это Boolean(5) === !!5 неверно: браузеры будут оценивать как true, но Boolean(5) возвращает объект Boolean, а !!5 возвращает логический литерал. При оценке браузеры будут переносить / развертывать литерал в объект, но typeof вернет 'object' для первого и 'boolean' для второго.

Pierpaolo
19 июля 2014 в 11:12
3

@Azder: Я пробовал как typeof(Boolean(5)), так и typeof(!!5) в Chrome, Firefox и IE8 (в консоли всех трех), и все они возвращают 'boolean'

Azder
24 июля 2014 в 05:36
0

Плохо, я думал о new Boolean(5), чего здесь нет. Во всяком случае, такая путаница - хорошая причина не использовать конструктор как функцию, а двойное отрицание (!!)

Gavin Jackson
18 сентября 2014 в 12:20
2

@ Stevo3000 - это не неправильный путь, просто неполный ... 'он преобразует не-логическое значение в логическое и инвертирует его , затем снова инвертирует его .'

Neurotransmitter
28 ноября 2016 в 18:53
0

Все браузеры, поддерживающие !, поддерживают !!. Поскольку это не оператор, это пара операторов.

geofflee
2 марта 2017 в 00:33
3

@sparkyShorts, если ваш код использует === для сравнения логических значений, тогда вы должны ввести приведение «истинных» значений к логическим значениям, используя !!, иначе ваши результаты будут неверными. Например, если предположить, что 0 означает ложь, а 1 означает истину, то 1 === true завершится ошибкой, тогда как !!1 === true работает правильно.

Dale Harris
20 марта 2018 в 17:15
1

@sparkyShorts Другой пример: рассмотрим свойство объекта obj.myString, которое может иметь строковое значение, но также может быть пустой строкой, нулем или неопределенным значением. Для записи if (!!obj.myString) { doSomething() }; гораздо меньше кода (хотя и более непонятного), чем для записи if (typeof obj.myString !== 'undefined' && obj.myString !== null && obj.myString !== '') { doSomething() };

ToolmakerSteve
27 октября 2020 в 20:02
0

@sparkyShorts: !!1 === true является избыточным. Его всегда можно сократить до !!1, что, как известно, приводит либо к true, либо к false. Это как сказать Boolean(x) === true: почему бы вам просто не сказать Boolean(x)?

Olivier de Jonge
4 августа 2021 в 18:35
0

Зачем вам использовать это в выражении if (!! object), если объект имеет значение null или undefined будет преобразовано в false, а объект, являющийся реальным объектом, будет преобразован в true?

avatar
Umesh Bhutada
21 апреля 2022 в 07:39
0

!! просто оператор НЕ дважды. чистый эффект - просто преобразовать что-либо, чтобы обеспечить логический тип данных. например

!!undefined равно false !!0 ложно !!ноль является ложным !!любой объект верен !!правда правда !!false ложно !0 верно !1 ложно

avatar
bit7
31 марта 2022 в 16:48
-1

В принципе, не используйте этот синтаксис. Это отправит людей в Google и, возможно, сюда. Вместо этого напишите описательный код.

Не пишите головокружительный код.

avatar
nguyenhoavuong
12 ноября 2021 в 03:56
0

!! не оператор, а просто оператор! оператор дважды

Но с javascript примените !! для преобразования объекта в логическое значение в большинстве случаев является избыточным и подробным, потому что:

Любой объект, значение которого не является неопределенным или нулевым, включая Логический объект, значение которого ложно, принимает значение true при передаче в условный оператор

Пример: if ({}) { console.log("{} is true")} // logs: "{} is true"

swpalmer
19 ноября 2021 в 15:18
0

«... логический объект, значение которого ложно, оценивается как истинное, когда ...» А? Я имею в виду, что JavaScript заслуживает ненависти за всю свою глупость, но я не верю, что это действительно так глупо, не так ли?

Tim Seguine
6 декабря 2021 в 20:32
0

@swpalmer jsfiddle.net/rsgqb5zp смотрите и удивляйтесь! Но менее бойко существует различие между объектами Boolean (big b), которые являются ссылочными типами, и boolean (small b), которые являются типами значений. Условие if проверяет ссылочные типы, чтобы узнать, не являются ли они пустыми или неопределенными.

avatar
Lucky Brain
21 января 2021 в 13:52
5

Важно помнить оценки для true и false в JavaScript :

  • Все, что имеет значение «Value» - это true (а именно правда ), например:

    • 101,
    • 3.1415,
    • -11,
    • "Lucky Brain",
    • new Object()
    • и, конечно же, true
  • Все без «значения» - это false (а именно ложь ), например:

    • 0,
    • -0,
    • "" (пустая строка),
    • undefined,
    • null,
    • NaN (не число)
    • и, конечно же, false

Применение оператора « логического НЕ » (!) вычисляет операнд, преобразует его в boolean и затем отменяет его. Применение его дважды приведет к отрицанию отрицания, эффективно преобразовав значение в boolean. Отсутствие оператора будет просто обычным присвоением точного значения. Примеры:

var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23

var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
  • value2 = value; назначает точный объект value, даже если он не boolean, следовательно, value2 не обязательно будет boolean.
  • value2 = !!value; назначает гарантированный boolean как результат двойного отрицания операнда value, и он эквивалентен следующему, но намного короче и читабельнее:

if (value) {
  value2 = true;
} else {
  value2 = false;
}
Andreas
21 января 2021 в 17:36
0

Как это добавить что-то новое или полезное к другим ответам?

Lucky Brain
22 января 2021 в 01:33
0

Ни один из других ответов не разъясняет концепции того, как JavaScript оценивает то, что является правдой или ложью . Начинающим разработчикам JavaScript необходимо знать, что оператор «not not» неявно использует исходный метод свободного сравнения вместо точных операторов === или !==, а также операцию скрытого приведения, которая происходит за кулисами, и я показываю это в пример, который я привожу.

avatar
Mile Mijatović
1 июля 2020 в 09:18
0

const foo = 'bar';
console.log(!!foo); // Boolean: true

! инвертирует (инвертирует) значение И всегда возвращает / производит логическое значение. Итак! 'Bar' вернет false (потому что 'bar' истинно => negated + boolean = false). С дополнительным! оператор, значение снова инвертируется, поэтому false становится истинным.

avatar
Lakmal
29 октября 2019 в 19:56
3

Чтобы преобразовать переменные JavaScript в логическое значение,

var firstname = "test";
//type of firstname is string
var firstNameNotEmpty = !!firstname;
//type of firstNameNotEmpty is boolean

javascript false для "", 0, undefined и null

javascript истина для числа, отличного от нуля, а не пустых строк, {}, [] и новой даты () Итак,

!!("test") /*is true*/
!!("") /*is false*/
avatar
Kirby L. Wallace
10 марта 2019 в 18:43
12

На этот вопрос дан довольно подробный ответ, но я хотел бы добавить ответ, который, я надеюсь, будет максимально упрощен и имеет смысл !! настолько просто, насколько это возможно.

Поскольку javascript имеет так называемые «истинные» и «ложные» значения, существуют выражения, которые при вычислении в других выражениях приведут к истинному или ложному условию, даже если проверяемое значение или выражение на самом деле не true или false.

Например:

if (document.getElementById('myElement')) {
    // code block
}

Если этот элемент действительно существует, выражение будет оценено как истинное, и блок кода будет выполнен.

Однако:

if (document.getElementById('myElement') == true) {
    // code block
}

... НЕ приведет к истинному состоянию, и блок кода не будет выполнен, даже если элемент действительно существует.

Почему? Поскольку document.getElementById() является «правдивым» выражением, которое будет оцениваться как истинное в этом операторе if(), но это не фактическое логическое значение true.

Двойное «не» в данном случае довольно простое. Это просто два not подряд.

Первый просто «инвертирует» истинное или ложное значение, в результате чего получается фактический логический тип, а затем второй «инвертирует» его обратно в исходное состояние, но теперь в фактическое логическое значение. Таким образом, у вас будет последовательность:

if (!!document.getElementById('myElement')) {}

и

if (!!document.getElementById('myElement') == true) {}

ОБА вернет истину, как и ожидалось.

avatar
مهدی عابدی برنامه نویس و مشاور
15 сентября 2018 в 04:37
0

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

hasMajor(){return this.major}//it return "(users major is)Science" 

но ответ для нас не важен, мы просто хотим проверить, есть ли у него основное или нет, и нам нужно логическое значение (истина или ложь), как мы его получаем:

вот так:

hasMajor(){ return !(!this.major)}

или аналогично

hasMajor(){return !!this.major)}

если this.major имеет значение, тогда !this.major вернет false, но поскольку значение имеет выходы, и нам нужно вернуть true, мы используем! дважды, чтобы вернуть правильный ответ !(!this.major)

avatar
appiconhero.co
25 июля 2018 в 03:52
10

Он заставляет все использовать логическое значение.

Например:

console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false

console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true

console.log(0 === false); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true
avatar
efkan
11 июля 2017 в 07:03
5

Возвращает логическое значение переменной.

Вместо этого можно использовать класс Boolean.

(прочтите описание кодов)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // writes `true`

А именно, Boolean(X) = !!X используется.

Пожалуйста, проверьте фрагмент кода ниже

let a = 0
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true.
console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // equals to `!!a`
console.log("\n") // newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes 1 value in boolean
console.log("\n") // newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // writes "" value in boolean
console.log("\n") // newline

a = "test"
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes "test" value in boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true
iPzard
26 января 2021 в 20:47
1

Проголосовал за .. Собственно, собирался ответить этим, если еще не здесь. Использование логического объекта imo - лучший подход с точки зрения удобочитаемости. Например, нет SO-вопроса «что делает Boolean» с 3k плюсами голосов - как в этом текущем вопросе.

avatar
Alireza
24 июня 2017 в 04:16
21

!! он использует операцию NOT дважды вместе, ! преобразует значение в boolean и инвертирует его, вот простой пример, чтобы увидеть, как работает !!:

Сначала место, которое у вас есть:

var zero = 0;

Затем вы выполняете !0, он будет преобразован в логическое значение и будет оценен в true, потому что 0 - это falsy, поэтому вы получите обратное значение и преобразуете его в логическое значение, поэтому оно будет оценено как true .

!zero; //true

, но нам не нужна обратная логическая версия значения, поэтому мы можем снова отменить ее, чтобы получить наш результат! Вот почему мы используем другой !.

По сути, !! убедитесь, что полученное значение является логическим, а не ложным, правдивым или строковым и т. Д.

Это похоже на использование функции Boolean в javascript, но простой и более короткий способ преобразовать значение в логическое значение:

var zero = 0;
!!zero; //false
avatar
Mystical
17 апреля 2017 в 14:47
2

!! аналогично использованию логического конструктора , или, возможно, больше похоже на 54375875> <4377377902> 54375875> логическая функция.

console.log(Boolean(null)); // Preffered over the Boolean object

console.log(new Boolean(null).valueOf()); // Not recommended for coverting non-boolean values

console.log(!!null); // A hacky way to omit calling the Boolean function, but essentially does the same thing. 


// The context you saw earlier (your example)
var vertical;

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical; 
        // Let's break it down: If vertical is strictly not undefined, return the boolean value of vertical and set it to this.vertical. If not, don't set a value for this.vertical (just ignore it and set it back to what it was before; in this case, nothing).   

        return this.vertical;
}

console.log( "\n---------------------" )

// vertical is currently undefined

console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = 12.5; // set vertical to 12.5, a truthy value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be true anyway
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = -0; // set vertical to -0, a falsey value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

Ложные значения в javascript принуждение к ложное и <5465875376519> истинное значение <2054657919> истина . Ложные и правдивые значения также могут использоваться в операторах if и будут по существу "отображаться" на их соответствующее логическое значение. Однако вам, вероятно, не придется часто использовать правильные логические значения, поскольку они в основном различаются по выводам (возвращаемым значениям).

Хотя это может показаться похожим на приведение, на самом деле это, скорее всего, простое совпадение, и оно не «построено» или специально создано для и не похоже на логическое приведение. Так что не будем называть это так.


Почему и как это работает

Для краткости это выглядит примерно так: ! ( !null ). Принимая во внимание, что null является ложным , поэтому !null будет истинным . Тогда !true будет ложным , и по существу вернет обратно к тому, что было раньше, за исключением того, что на этот раз как правильное логическое значение (или даже наоборот с истинными значениями такими как {} или 1).


Возвращаясь к вашему примеру

В целом контекст, который вы видели, просто регулирует this.vertical в зависимости от того, определен ли vertical, и если да; ему будет присвоено результирующее логическое значение vertical, в противном случае оно не изменится. Другими словами, если определено vertical; this.vertical будет установлено его логическое значение, в противном случае оно останется прежним. Думаю, это само по себе является примером того, как вы могли бы использовать !! и что он делает.


Пример вертикального ввода / вывода

Запустите этот пример и поиграйте с вертикальным значением во входных данных. Посмотрите, к чему приводит результат, чтобы вы могли полностью понять код вашего контекста. В поле ввода введите любое допустимое значение javascript. Не забудьте включить цитаты, если вы тестируете строку. Не обращайте внимания на код CSS и HTML, просто запустите этот фрагмент и поэкспериментируйте с ним. Однако вы, возможно, захотите взглянуть на код javascript, не связанный с DOM (использование конструктора Example и вертикальной переменной).

var vertical = document.getElementById("vertical");
var p = document.getElementById("result");

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical;   

        return this.vertical;
}

document.getElementById("run").onclick = function()
{

  p.innerHTML = !!( new Example(eval(vertical.value)).vertical );
  
}
input
{
  text-align: center;
  width: 5em;
} 

button 
{
  margin: 15.5px;
  width: 14em;
  height: 3.4em;
  color: blue;
}

var 
{
  color: purple;
}

p {
  margin: 15px;
}

span.comment {
  color: brown;
}
<!--Vertical I/O Example-->
<h4>Vertical Example</h4>
<code id="code"><var class="var">var</var> vertical = <input type="text" id="vertical" maxlength="9" />; <span class="comment">// enter any valid javascript value</span></code>
<br />
<button id="run">Run</button>
<p id="result">...</p>

avatar
Wouter Vanherck
29 марта 2017 в 07:15
6

Увидев все эти замечательные ответы, я хотел бы добавить еще одну причину использования !!. В настоящее время я работаю в Angular 2-4 (TypeScript), и я хочу вернуть логическое значение как false, когда мой пользователь не аутентифицирован. Если он не аутентифицирован, строка токена будет null или "". Я могу сделать это, используя следующий блок кода:

public isAuthenticated(): boolean {
   return !!this.getToken();
}
avatar
Ryan Taylor
19 октября 2016 в 21:00
9

Я просто хотел добавить, что

if(variableThing){
  // do something
}

совпадает с

if(!!variableThing){
  // do something
}

Но это может быть проблемой, когда что-то не определено.

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

Уловка здесь в том, что цепочка && возвращает первое найденное ложное значение - и это может быть передано в оператор if и т. Д. Итак, если b.foo не определен, он вернет undefined и пропустит оператор b.foo.bar, и мы не получим ошибки.

Вышеупомянутый возврат не определен, но если у вас есть пустая строка, false, null, 0, undefined, эти значения вернутся, и как только мы встретим их в цепочке - [] и {} оба являются «правдивыми» и мы продолжим вниз по так называемой «цепочке &&» к следующему значению справа.

PS Другой способ сделать то же самое - (b || {}).foo, потому что если b не определено, то b || {} будет {}, и вы получите доступ к значению в пустом объекте ( нет ошибки) вместо попытки получить доступ к значению в "undefined" (вызывает ошибку). Итак, (b || {}).foo то же самое, что b && b.foo, а ((b || {}).foo || {}).bar то же самое, что b && b.foo && b.foo.bar.

Ryan Taylor
10 января 2017 в 17:36
0

хороший момент - изменил свой ответ. Это происходит с объектом, только если он вложен на три уровня в глубину, потому что, как вы сказали, ({}).anything даст undefined

avatar
Abhay Dixit
15 июля 2016 в 10:25
5

Используйте логический оператор НЕ два раза
это означает !true = false и !!true = true

avatar
GreQ
25 мая 2016 в 10:18
20

Думаю, стоит упомянуть, что условие, объединенное с логическим И / ИЛИ, не будет возвращать логическое значение, но последний успех или первый сбой в случае && и первый успех или последний провал в случае || цепочки условий.

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

Чтобы преобразовать условие в истинный логический литерал, мы можем использовать двойное отрицание:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true
avatar
Damian Yerrick
6 марта 2016 в 14:46
11

Операторы if и while и оператор ? используют значения истинности, чтобы определить, какую ветвь кода выполнить. Например, числа 0 и NaN и пустая строка являются ложными, но другие числа и строки верны. Объекты верны, но неопределенное значение и null неверны.

Оператор двойного отрицания !! вычисляет истинное значение значения. Фактически это два оператора, где !!x означает !(!x) и ведет себя следующим образом:

  • Если x - ложное значение, !x равно true, а !!x - false.
  • Если x - истинное значение, !x равно false, а !!x - true.

При использовании на верхнем уровне логического контекста (if, while или ?) оператор !! поведенчески не работает. Например, if (x) и if (!!x) означают одно и то же.

Практическое использование

Однако он имеет несколько практических применений.

Одно из применений - сжатие с потерями объекта до его истинного значения, чтобы ваш код не содержал ссылку на большой объект и не поддерживал его в действии. Присвоение переменной !!some_big_object вместо some_big_object позволяет отказаться от нее для сборщика мусора. Это полезно для случаев, когда создается объект или ложное значение, такое как null, или неопределенное значение, например обнаружение функции браузера.

Другое использование, о котором я упоминал в ответе о соответствующем !! Оператор, имеет инструменты "lint", которые ищут типичные опечатки и диагностику печати. Например, как в C, так и в JavaScript несколько типичных опечаток для логических операций приводят к другому поведению, вывод которого не совсем такой, как логический:

  • if (a = b) - это присвоение, за которым следует использование значения истинности b; if (a == b) - сравнение на равенство.
  • if (a & b) - побитовое И; if (a && b) - логическое И. 2 & 5 - это 0 (ложное значение); 2 && 5 верно.

Оператор !! убеждает инструмент lint в том, что вы написали именно то, что вы имели в виду: выполните эту операцию, а затем возьмите истинное значение результата.

Третье использование - создание логического XOR и логического XNOR. И в C, и в JavaScript a && b выполняет логическое И (истинно, если обе стороны верны), а a & b выполняет побитовое И. a || b выполняет логическое ИЛИ (истинно, если хотя бы одно из них истинно), а a | b выполняет побитовое ИЛИ. Существует побитовое XOR (исключающее ИЛИ) как a ^ b, но нет встроенного оператора для логического XOR (истинно, если истинна ровно одна сторона). Например, вы можете разрешить пользователю вводить текст ровно в одно из двух полей. Что вы можете сделать, так это преобразовать каждое в значение истинности и сравнить их: !!x !== !!y.

avatar
Greg Gum
4 декабря 2015 в 12:50
10

!!x - это сокращение для Boolean(x)

Первый удар заставляет движок js запускать Boolean(x), но также имеет побочный эффект инвертирования значения. Таким образом, второй удар устраняет побочный эффект.

avatar
GibboK
1 июля 2015 в 07:29
4

Некоторые операторы в JavaScript выполняют неявное преобразование типов, а иногда используется для преобразования типа.

Унарный оператор ! преобразует свой операнд в логическое значение и инвертирует его.

Этот факт приводит к следующей идиоме, которую вы можете увидеть в исходном коде:

!!x // Same as Boolean(x). Note double exclamation mark
avatar
ruffin
29 апреля 2015 в 18:14
75

Так много ответов делают половину работы. Да, !!X можно прочитать как «истинность X [представленного как логическое]». Но !!, с практической точки зрения, не так важно для выяснения того, является ли одна переменная (или даже если многие переменные) правдивой или ложной. !!myVar === true - это то же самое, что и myVar. Сравнение !!X с "реальным" логическим значением бесполезно.

Единственное, что вы получаете с !!, - это возможность проверять достоверность нескольких переменных относительно друг друга повторяющимся, стандартизованным (и дружественным к JSLint) способом.

Простое преобразование :(

То есть ...

  • 0 === false - это false.
  • !!0 === false - это true.

Вышесказанное не очень полезно. if (!0) дает те же результаты, что и if (!!0 === false). Я не могу придумать хороший случай для преобразования переменной в логическое значение и последующего сравнения с «истинным» логическим значением.

См. "== and! =" Из направлений JSLint (примечание: Крокфорд немного перемещает свой сайт; эта ссылка может умереть в какой-то момент), чтобы немного узнать, почему:

Операторы == и! = Перед сравнением выполняют приведение типов. Это плохо, потому что приводит к истинному значению '\ t \ r \ n' == 0. Это может замаскировать типовые ошибки. JSLint не может надежно определить, правильно ли используется ==, поэтому лучше вообще не использовать == и! = И всегда использовать вместо них более надежные операторы === и! ==.

Если вас беспокоит только то, что значение является правдивым или ложным, используйте краткую форму. Вместо
(foo != 0)

просто скажите
(foo)

и вместо
(foo == 0)

сказать
(!foo)

Обратите внимание, что есть некоторые неинтуитивные случаи, когда логическое значение будет приведено к числу (true приведено к 1 и false к 0) при сравнении логического значения с числом. В этом случае !! может быть полезен в умственном отношении. Хотя, опять же, , это случаи, когда вы сравниваете не логическое значение с жестко типизированным логическим, что, я думаю, является серьезной ошибкой.

>
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║               Original                ║    Equivalent     ║  Result   ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam")   ║ if (-1 == 1)      ║ undefined ║
║ if (-1 == false) console.log("spam")  ║ if (-1 == 0)      ║ undefined ║
║   Order doesn't matter...             ║                   ║           ║
║ if (true == -1) console.log("spam")   ║ if (1 == -1)      ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam      ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam")           ║ if (truthy)       ║ spam      ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

А в зависимости от вашего двигателя все становится еще безумнее. WScript, например, получает приз.

function test()
{
    return (1 === 1);
}
WScript.echo(test());

Из-за некоторого исторического джайва Windows, в окне сообщения будет выведено -1! Попробуйте в командной строке cmd.exe и убедитесь! Но WScript.echo(-1 == test()) по-прежнему дает 0 или false в WScript. Посмотри в сторону. Это ужасно.

Сравнение правды :)

Но что, если у меня есть два значения, которые мне нужно проверить на равную истинность / ложность?

Представьте, что у нас есть myVar1 = 0; и myVar2 = undefined;.

  • myVar1 === myVar2 равно 0 === undefined и явно неверно.
  • !!myVar1 === !!myVar2 - это !!0 === !!undefined и верно! Та же правда! (В данном случае оба «имеют правдивость лжи».)

Итак, единственное место, где вам действительно нужно было бы использовать «переменные с логическим преобразованием», было бы в ситуации, когда вы проверяете, имеют ли обе переменные одинаковую правдивость, верно? То есть используйте !!, если вам нужно увидеть, являются ли две вары оба правдивыми или оба ложными (или нет), то есть равны (или нет) правдивость .

Я не могу придумать отличного, не надуманного варианта использования для этого навскидку. Может быть, у вас есть "связанные" поля в форме?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age " 
        + "for your spouse or leave all spouse fields blank.";
}

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

Хотя даже в этом случае !! действительно лишний. Одного ! было достаточно для преобразования в логическое значение, и вы просто проверяете равенство.


ИЗМЕНИТЬ 24 октября 2017 г., 6 февраля 19 г.:

Сторонние библиотеки, ожидающие явных логических значений

Вот интересный случай ... !! может быть полезен, когда сторонние библиотеки ожидают явных логических значений.

Реагировать

Например, False в JSX (React) имеет особое значение, которое не срабатывает при простой ложности. Если вы пытались вернуть в JSX что-то вроде следующего, ожидая int в messageCount ...

{messageCount && <div>You have messages!</div>}

... вы можете быть удивлены, увидев, что React отображает 0, когда у вас нет сообщений. Вы должны явно вернуть false, чтобы JSX не отображался. Приведенный выше оператор возвращает 0, который JSX с радостью отображает, как и должно. Он не может сказать, что у вас не было Count: {messageCount}.

  • Одно исправление связано с bangbang, который переводит 0 в !!0, то есть false:
    {!!messageCount && <div>You have messages!</div>}

  • Документы JSX предлагают вам быть более явным, написать код с комментариями и использовать сравнение для принудительного преобразования в логическое значение.
    {messageCount > 0 && <div>You have messages!</div>}

  • Мне удобнее самому справляться с ложью с помощью троичной системы -
    {messageCount ? <div>You have messages!</div> : false}

Машинопись

То же самое и в Typescript: если у вас есть функция, которая возвращает логическое значение (или вы присваиваете значение логической переменной), вы [обычно] не можете вернуть / присвоить логическое значение y; это должно быть строго типизированное логическое значение. Это означает, что , если myObject строго типизирован, , return !myObject; работает для функции, возвращающей логическое значение, а return myObject; - нет. Вы должны return !!myObject (или привести к правильному логическому типу другим способом), чтобы соответствовать ожиданиям Typescript.

Исключение для машинописного текста? Если myObject был any, вы вернулись на Дикий Запад JavaScript и можете вернуть его без !!, даже если ваш возвращаемый тип является логическим.

Имейте в виду, что эти являются соглашениями JSX и Typescript , а не присущими JavaScript .

Но если вы видите странные символы 0 в визуализированном JSX, подумайте о том, что не нужно управлять ложью.

jk7
6 мая 2015 в 20:41
0

Хорошее объяснение. Так бы вы сказали !! не является строго обязательным в этом примере обнаружения рабочих функций? if (!!window.Worker)

ruffin
6 мая 2015 в 20:54
2

Нет, тебе это не понадобится. Истина и true «внешне» действуют точно так же в if. Я продолжаю попытки, но не могу придумать причину, чтобы предпочесть приведение правдивости к логическому значению за пределами своего рода запутанного случая «сравнения правдивости», описанного выше, за исключением удобочитаемости, если вы повторно используете значение позже, как в q Пример библиотеки. Но даже в этом случае это ярлык с потерей информации, и я бы сказал, что вам лучше каждый раз оценивать правдивость.

avatar
JeevanReddy Avanaganti
4 марта 2015 в 08:25
5

вот фрагмент кода из angular js

var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame ||
                                $window.mozRequestAnimationFrame;

 var rafSupported = !!requestAnimationFrame;

их намерение состоит в том, чтобы установить rafSupported в значение true или false в зависимости от доступности функции в requestAnimationFrame

это может быть достигнуто путем проверки в целом следующим образом:

if(typeof  requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;

короткий путь можно использовать !!

rafSupported = !!requestAnimationFrame ;

поэтому, если requestAnimationFrame была назначена функция потом ! requestAnimationFrame будет false и еще один! из этого было бы правдой

если для requestAnimationFrame было присвоено значение undefined, то ! requestAnimationFrame и еще один! из этого было бы ложным

avatar
user3698272
28 июня 2014 в 03:35
2
a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined

Для !a он проверяет, определен ли a НЕ , а !!a проверяет, определена ли переменная.

!!a совпадает с !(!a). Если a определено, a равно true, !a равно false и !!a равно true.

.
avatar
Warren Davis
24 апреля 2014 в 13:05
9

Здесь масса отличных ответов, но если вы дочитали до этого места, это помогло мне «понять». Откройте консоль в Chrome (и т. Д.) И начните вводить:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)

Естественно, все это то же самое, что просто набирать !! someThing, но добавленные круглые скобки могут помочь сделать это более понятным.

avatar
Navin Rauniyar
9 апреля 2014 в 04:29
17

Конструкция !! - это простой способ превратить любое выражение JavaScript в его логический эквивалент.

Например: !!"he shot me down" === true и !!0 === false.

ruffin
29 апреля 2015 в 17:38
2

Очень близко к важному различию. Ключ в том, что 0 === false ложно, а !!0 === false верно.

avatar
Benny
22 февраля 2013 в 23:45
180

Заварить чай:

!! не оператор. Это двойное использование ! - логического оператора «не».


Теоретически:

! определяет «истину» того, чем не является значение:

  • На самом деле false не является true (поэтому !false результаты в true )

  • На самом деле true не является false (поэтому !true результаты в false )


!! определяет "истинность" того, что такое значение , а не не:

  • На самом деле true не не true (поэтому !!true приводит к true <12577118438>true <12577118438>true <12577118438>true <12577118438>

  • На самом деле false не не false (поэтому !!false приводит к false <12475778411>


То, что мы хотим определить при сравнении, - это «истина» относительно значения ссылки, а не значение самой ссылки. Существует вариант использования, когда мы можем захотеть узнать правду о значении, даже если мы ожидаем, что значение будет false (или falsey), или если мы ожидаем, что значение не будет typeof boolean.


На практике:

Рассмотрим краткую функцию, которая обнаруживает функциональные возможности (и в данном случае совместимость с платформой) посредством динамического набора текста (также известного как «утиный ввод»). Мы хотим написать функцию, которая возвращает true, если браузер пользователя поддерживает элемент HTML5 <audio>, но мы не хотим, чтобы функция выдавала ошибку, если <audio> не определено; и мы не хотим использовать try ... catch для обработки любых возможных ошибок (потому что они грубые); , а также мы не хотим использовать проверку внутри функции, которая не будет последовательно раскрывать правду об этой функции (например, document.createElement('audio') все равно создаст элемент с именем <audio>, даже если HTML5 <audio> не поддерживается).


Вот три подхода:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

Каждая функция принимает аргумент для поиска <tag> и attribute, но каждая из них возвращает разные значения в зависимости от того, что определяют сравнения.

Но подождите, это еще не все!

Некоторые из вас, вероятно, заметили, что в этом конкретном примере можно просто проверить свойство, используя несколько более производительное средство проверки того, имеет ли рассматриваемый объект собственность. Это можно сделать двумя способами:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

Мы отвлекаемся ...

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

Tom Auger
6 апреля 2016 в 13:27
6

совершенно потрясающий ответ, но я не вижу полезности !! построить. Поскольку оператор if() уже преобразует выражение в логическое значение, явное преобразование возвращаемого значения функции тестирования в логическое значение является избыточным - поскольку «истинность» === true в отношении оператора if() в любом случае. Или мне не хватает сценария, в котором вам НУЖНО правдивое выражение, чтобы на самом деле быть логическим true?

Benny
31 мая 2018 в 15:41
5

Операторы @TomAuger if() приводят логическое значение к ложным значениям, но говорят, что вы действительно хотите установить логический флаг для объекта - он не будет преобразовывать его, как оператор if(). Например, object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat() установит либо true, либо false вместо реального возвращаемого значения. Другой пример: все администраторы имеют id из 0, а неадминистраторы имеют идентификатор 1 или выше. Чтобы получить true, если кто-то не является администратором, вы можете сделать person.isNotAdmin = !!admin.id. Мало вариантов использования, но когда есть, то кратко.

avatar
Salman A
15 мая 2012 в 09:06
523

!!expr (два оператора !, за которыми следует выражение) возвращает логическое значение (true или false) в зависимости от истинности выражения. Это имеет больше смысла при использовании с небулевыми типами. Рассмотрим эти примеры, особенно третий пример и далее:

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy
          !!(1/0) === true  // Infinity is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined value is falsy
      !!undefined === false // undefined primitive is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!
Camilo Martin
18 декабря 2012 в 08:05
72

Стоит отметить: !!new Boolean(false) // true

Camilo Martin
18 декабря 2012 в 08:06
52

... Но также !!Boolean(false) // false

Salman A
18 декабря 2012 в 08:15
111

new Boolean(false) - это объект, и объект является правдивым, даже если он содержит ложное значение!

Yashwin Munsadwala
16 июня 2021 в 17:27
0

Определенное предложение добавить !!undefined //false к этому замечательному ответу!

avatar
rob_james
24 апреля 2012 в 12:22
-4

Это действительно удобный способ проверить наличие undefined, "undefined", null, "null", ""

if (!!var1 && !!var2 && !!var3 && !!var4 ){
   //... some code here
}
rob_james
28 октября 2012 в 17:22
0

Почему? Мне все еще нужно знать, что в переменных от 1 до 4 есть значения.

nalply
29 октября 2012 в 07:31
8

Потому что операторы && уже «конвертируют» свои операторы в логические.

rob_james
29 октября 2012 в 21:25
0

да - круто! Ваше здоровье. Для протокола я пытался указать, что было бы хорошо проверить множество значений. Можете ли вы представить себе это без логического преобразования ?! Ментальный! В любом случае, это хорошо знать. То же самое происходит с ||?

nalply
30 октября 2012 в 09:16
7

Я должен отозвать свой комментарий. Я был неправ. «Преобразует» не операторы &&, а оператор if. Может быть, хороший вопрос по StackOverflow?

aikeru
21 августа 2013 в 21:18
3

Я думаю, что это оператор &&, как если бы вы удалили окружающее if, вы все равно получите все то же поведение выражения, которое if просто проверяет результат ...

avatar
Prakash
23 марта 2011 в 11:53
27

Он имитирует поведение функции приведения Boolean(). Первый NOT возвращает логическое значение независимо от того, какой операнд он задан. Второй NOT отрицает это значение Boolean и, таким образом, дает логическое значение true переменной. Конечный результат такой же, как при использовании функции Boolean() для значения.

avatar
Sergey Ilinsky
2 декабря 2010 в 20:21
10

​​Двойное логическое отрицание. Часто используется для проверки, не является ли значение неопределенным.

avatar
Justin Johnson
10 сентября 2009 в 21:19
17

Это не один оператор, а два. Это эквивалентно следующему и является быстрым способом преобразования значения в логическое значение.

val.enabled = !(!enable);
avatar
Christoph
10 сентября 2009 в 21:15
83

!!foo дважды применяет унарный оператор not и используется для преобразования в логический тип, аналогично использованию унарного плюса +foo для преобразования в число и объединения пустой строки ''+foo для преобразования в строку.

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

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo
Seamus
7 октября 2010 в 12:53
0

Но тогда вы можете столкнуться с проблемами с instanceof. new Boolean (1) instanceof Object -> true !! 1 instanceof Object -> false

Christoph
8 октября 2010 в 09:46
15

нет, вы не можете: обратите внимание, что функции конструктора вызываются без new - как явно указано в моем ответе

DiegoDD
3 июня 2013 в 18:13
2

фантастика! Это полезно для небольшого взлома, когда вам нужно оценить строки с «0» как ложные вместо истины. (т.е. при чтении значений из выборок, потому что они читаются как String). Итак, если вы хотите рассматривать «0» как отрицательное значение (логическое значение false), предполагая, что x="0" просто выполните: x=!!+x; //false, который совпадает с Boolean(Number(x)) Number (или + x), преобразует строку «0» в 0, который ДЕЙСТВИТЕЛЬНО оценивает значение false, а затем Boolean (!! x) преобразует его в boolean напрямую. Очень просто!

placeybordeaux
29 декабря 2015 в 23:46
2

@DiegoDD, почему бы вам выбрать !!+x против x !== "0"?

DiegoDD
5 января 2016 в 18:26
0

@placeybordeaux, потому что, например, вы можете захотеть преобразовать значение и присвоить его другой переменной, независимо от того, собираетесь ли вы сравнивать его с чем-то другим или нет.

avatar
Annika Backstrom
10 сентября 2009 в 17:29
22

! является логическим «не», которое, по сути, приводит значение «enable» к его логической противоположности. Второй ! переворачивает это значение. Итак, !!enable означает «не включить», что дает вам значение enable как логическое.

avatar
Bill the Lizard
10 сентября 2009 в 17:28
28

Это двойная операция not. Первый ! преобразует значение в логическое и инвертирует его логическое значение. Второй ! инвертирует логическое значение обратно.

avatar
Tom Ritter
10 сентября 2009 в 17:28
912

Это ужасно непонятный способ преобразования типа.

! - это НЕ . Итак, !true - это false, а !false - это true. !0 - это true, а !1 - false.

Итак, вы конвертируете значение в логическое, затем инвертируете его, а затем снова инвертируете.

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);
cllpse
10 сентября 2009 в 17:38
85

!! ложь = ложь. !! правда = правда

Ben Regenspan
13 октября 2010 в 16:26
111

Неужели вариант "намного проще для понимания" действительно намного проще для понимания здесь? Проверка на 0 - это не фактическая проверка на 0, а проверка на несколько странный список значений, которые Javascript считает равными 0. userId ? true : false более ясно показывает, что происходит преобразование, и обрабатывает случай, когда значение userId могло быть явно установлено на undefined

adamJLev
24 октября 2010 в 23:36
70

У моего мозга нет проблем с декодированием !!var в Boolean(var) .. и !! быстрее (меньше инструкций для обработки) и короче, чем альтернативы.

slim
21 августа 2020 в 16:19
5

!!false ложно. false != 0 верно. Так что они не эквивалентны. !! служит полезной цели приведения чего-либо к логическому значению.

ToolmakerSteve
27 октября 2020 в 20:17
9

Я понимаю, что вы написали этот ответ много лет назад, но в интересах его уточнения на сегодняшний день: Проще всего понять, чтобы сказать то, что вы имеете в виду, : Boolean(x). Я не считаю, что ни один из ваших вариантов легко понять. Хуже того, есть по крайней мере один случай, когда использование оператора равенства x != 0 дает другой результат, чем Boolean(x) или !!x: попробуйте [] для x. Кроме того, если вам нравится использовать оператор равенства, чтобы получить его правила «истинности», почему бы вам не сделать более очевидный (userId == true) вместо (userId != 0)?

Maik Lowrey
8 апреля 2021 в 20:33
2

@cllpse Вы имеете в виду !! false === false и !! true === true? ;-)

Sam Johnson
13 августа 2021 в 06:42
0

Однако стоит отметить, что !! переносится практически на любой язык C-стиля.

avatar
Paul McMillan
10 сентября 2009 в 17:27
33

Преобразует суффикс в логическое значение.

avatar
Crescent Fresh
10 сентября 2009 в 17:26
107

!! преобразует значение справа от него в эквивалентное логическое значение. (Подумайте о способе бедняков "приведения типов"). Его намерение обычно состоит в том, чтобы передать читателю, что код не заботится какое значение находится в переменной, а какое оно «истинное» значение.

>
Daniel A. White
10 сентября 2009 в 17:28
4

Или в случае логического значения справа ничего не делает.

Crescent Fresh
10 сентября 2009 в 17:34
3

@Daniel: ! по-прежнему переворачивает значение вправо. В случае логического значения крайний правый ! отрицает значение, а крайний левый ! снова отрицает его. Чистый эффект состоит в том, что изменений нет, но большинство движков будут генерировать коды операций для двойного отрицания.

CodyBugstein
6 мая 2016 в 23:37
0

Но в чем суть? Если я сделаю if(0){..., Javascript уже знает, что это неверно. Почему лучше сказать if(!!0){...?

mix3d
22 сентября 2016 в 12:59
0

речь идет о переменных, о которых вы могли не знать его содержимое; если это может быть целое число или строка, объект или ноль, undefined и т. д. Это простой способ проверить существование.

avatar
Darren Clark
24 апреля 2009 в 08:33
12

Я подозреваю, что это остатки C ++, где люди переопределяют! оператор, но не оператор логического типа.

Итак, чтобы получить отрицательный (или положительный) ответ в этом случае, вам сначала нужно использовать! оператор, чтобы получить логическое значение, но если вы хотите проверить положительный случай, используйте !!.

avatar
Steve Harrison
24 апреля 2009 в 08:20
29

Похоже, что оператор !! приводит к двойному отрицанию.

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true
avatar
Greg
24 апреля 2009 в 08:18
59

Это просто логический оператор НЕ, дважды - он используется для преобразования чего-либо в логическое значение, например:

true === !!10

false === !!0
Lightness Races in Orbit
9 ноября 2011 в 10:34
44

@ Даррен: Он не сравнивает типы; он сообщает вам, каковы результаты, записывая утверждения в своем ответе.