Как? ~ (А не тильда/бит bang tilde) изменяют результат вызова метода "содержит/включены"?
Если вы читаете комментарии на странице jQuery inArray
здесь, есть интересное объявление:
!!~jQuery.inArray(elm, arr)
Теперь я считаю, что точка с двойным восклицанием преобразует результат в тип boolean
со значением true
. То, что я не понимаю, в чем заключается использование оператора тильды (~
) во всем этом?
var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }
Рефакторинг инструкции if
:
if (!!~jQuery.inArray("one", arr)) { alert("Found"); }
Структура:
jQuery.inArray("one", arr) // 0
~jQuery.inArray("one", arr) // -1 (why?)
!~jQuery.inArray("one", arr) // false
!!~jQuery.inArray("one", arr) // true
Я также заметил, что если я поставил тильду спереди, результат будет -2
.
~!!~jQuery.inArray("one", arr) // -2
Я не понимаю цели тильды здесь. Может кто-нибудь объяснить это или указать мне на ресурс?
Ответы
Ответ 1
Оператор тильды фактически не является частью jQuery - он побитовым оператором NOT в самом JavaScript.
См . Великую тайну Тильды (~).
Вы получаете странные числа в своих экспериментах, потому что вы выполняете поразрядную логическую операцию над целым числом (которое, насколько мне известно, может храниться как два дополнения или что-то в этом роде...)
Два дополнения объясняют, как представлять число в двоичном формате. Думаю, я был прав.
Ответ 2
Там определенная причина, по которой вы иногда видите ~
, применяемую перед $.inArray
.
В принципе,
~$.inArray("foo", bar)
- более короткий способ сделать
$.inArray("foo", bar) !== -1
$.inArray
возвращает индекс элемента в массиве, если найден первый аргумент, и возвращает -1, если его не найдено. Это означает, что если вы ищете логическое значение "это значение в массиве?", Вы не можете выполнить логическое сравнение, так как -1 является правдивым значением, а когда $.inArray возвращает 0 (значение фальшивости), это означает, что он действительно найден в первом элементе массива.
Применение побитового оператора ~
приводит к тому, что -1
становится 0
и вызывает 0, чтобы стать `-1. Таким образом, не обнаруживая значения в массиве и применяя побитовые NOT результаты в ложном значении (0), а все остальные значения возвращают не-0 чисел и будут представлять правдивый результат.
if (~$.inArray("foo", ["foo",2,3])) {
// Will run
}
И он будет работать по назначению.
Ответ 3
!!~expr
оценивает значение false
когда expr
- -1
противном случае - true
.
Это то же самое, что и expr != -1
, только сломанный *
Он работает, потому что побитовые операции JavaScript преобразуют операнды в 32-разрядные целые числа со знаком в двух дополнительных форматах. Таким образом, !!~-1
оценивается следующим образом:
-1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two complement representation of -1
~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
!0 = true // ! is logical not (true for falsy)
!true = false // duh
Значение, отличное от -1
будет иметь как минимум один бит, равный нулю; инвертирование, это создаст правдивую ценность; применение !
оператор дважды к истинному значению возвращает boolean true.
При использовании с .indexOf()
и мы хотим только проверить, является ли результат -1
или нет:
!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns 0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns 1, the expression evaluates to true
* !!~8589934591
оценивает значение false, поэтому это мерзость не могут быть надежно использованы для тестирования -1
.
Ответ 4
~foo.indexOf(bar)
является общим сокращением для представления foo.contains(bar)
, поскольку функция contains
не существует.
Как правило, приведение в boolean необязательно из-за концепции JavaScript с "ложными" значениями. В этом случае он использовал для вывода функции true
или false
.
Ответ 5
jQuery.inArray()
возвращает -1
для "not found" , дополнением которого (~
) является 0
. Таким образом, ~jQuery.inArray()
возвращает значение falsy (0
) для "not found" и правное значение (отрицательное целое число) для "найденного". !!
затем формализует фальшивость/правду в вещественное булево false
/true
. Итак, !!~jQuery.inArray()
даст true
для "found" и false
для "not found" .
Ответ 6
~
для всех 4 байтов int
равно этой формуле -(N+1)
SO
~0 = -(0+1) // -1
~35 = -(35+1) // -36
~-35 = -(-35+1) //34
Ответ 7
Оператор ~
является оператором побитового дополнения. Integer результат из inArray()
равен либо -1, когда элемент не найден, или некоторое неотрицательное целое число. Поразрядное дополнение -1 (представленное в двоичном виде как все 1 бит) равно нулю. Побитовое дополнение любого неотрицательного целого всегда отличное от нуля.
Таким образом, !!~i
будет true
, когда целое число "i" является неотрицательным целым числом, а false
, когда "i" равно -1.
Обратите внимание, что ~
всегда зацикливает свой операнд на целое; то есть он приводит к нецелочисленным значениям с плавающей запятой в целое число, а также к нечисловым значениям.
Ответ 8
Тильда побитовое НЕ - инвертирует каждый бит значения. Как правило, если вы используете ~
для числа, его знак будет инвертирован, тогда будет вычтено 1.
Таким образом, когда вы делаете ~0
, вы получаете -1 (0 инвертировано - 0, вычитание 1 равно -1).
Это по сути сложный, супер-микро-оптимизированный способ получения значения, которое всегда является логическим.
Ответ 9
Вы правы: этот код вернет false
, когда вызов indexOf
возвращает -1; иначе true
.
Как вы говорите, было бы гораздо разумнее использовать что-то вроде
return this.modifiedPaths.indexOf(path) !== -1;
Ответ 10
Оператор ~
является побитовым оператором NOT. Это означает, что он принимает число в двоичной форме и превращает все нули в единицы и единицы в нули.
Например, число 0 в двоичном формате равно 0000000
, а -1 - 11111111
. Аналогично, 1 является 00000001
в двоичном выражении, а -2 - 11111110
.
Ответ 11
Моя догадка заключается в том, что он существует, потому что это несколько символов короче (авторы библиотеки всегда после этого). Он также использует операции, выполняющие только несколько машинных циклов при компиляции в собственный код (в отличие от сравнения с числом).
Я согласен с другим ответом на то, что это излишний, но, возможно, может иметь смысл в жесткой петле (требует оценки производительности, однако, в противном случае может оказаться преждевременной оптимизацией.)
Ответ 12
Я предполагаю, что это поразрядная операция, это самый быстрый (вычислительно дешевый) способ проверить, отображается ли путь в modifiedPaths.
Ответ 13
Как (~(-1)) === 0
, так:
!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false