Как же так!~ (не Тильда/банг банг Тильда) изменить результат 'содержит/в комплекте' метод выбора звонка?
если Вы читаете комментарии в 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
I также заметил, что если я поставлю Тильду впереди, результат будет -2
.
~!!~jQuery.inArray("one", arr) // -2
Я не понимаю цели Тильды здесь. Может кто-нибудь объяснить это или указать мне на ресурс?
13 ответов:
оператор tilde на самом деле не является частью jQuery вообще - это побитовый оператор NOT в самом JavaScript.
посмотреть великая тайна Тильды (~).
вы получаете странные числа в своих экспериментах, потому что вы выполняете побитовую логическую операцию над целым числом (которое, насколько я знаю, может храниться как дополнение к двум или что-то в этом роде...)
два объясняет, как представить число в двоичной системе. Думаю, я был прав.
есть особая причина, которую вы иногда увидите
~
применяется перед$.inArray
.по сути,
~$.inArray("foo", bar)
это более короткий способ сделать
$.inArray("foo", bar) !== -1
$.inArray
возвращает индекс элемента в массиве, если первый аргумент и возвращает -1, если его не нашли. Это означает, что если вы ищете логическое "это значение в массиве?", вы не можете сделать логическое сравнение, так как -1 является истинным значением, и когда $.inArray возвращает 0 (ложное значение), это означает, что его фактически нашли в первом элементе массива.применение
~
побитовый оператор вызывает-1
стать0
, и вызывает 0, чтобы стать ' -1. Таким образом, не находя значения в массиве и применяя побитовое не приводит к ложному значению (0), а все остальные значения будут возвращать номера, отличные от 0, и будут представлять собой истинный результат.if (~$.inArray("foo", ["foo",2,3])) { // Will run }
и это будет работать как задумано.
!!~expr
значениеfalse
, когдаexpr
и-1
иначеtrue
.
Это же какexpr != -1
, только сломана*
это работает, потому что JavaScript побитовые операции преобразуйте операнды в 32-разрядные целые числа со знаком в формате дополнения two. Таким образом
!!~-1
вычисляется следующим образом:-1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's 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
будет иметь по крайней мере один бит, равный нулю; инвертирование создаст истинное значение; применение!
оператор дважды к истинному значению возвращает логическое значение 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
.
jQuery.inArray()
возвращает-1
для "не найдено", чье дополнение (~
) составляет0
. Таким образом,~jQuery.inArray()
возвращает значение ложь (0
) для "не найдено", и истинное значение (отрицательное целое число) для "найдено".!!
затем формализует ложь / истину в реальное булевоfalse
/true
. Итак,!!~jQuery.inArray()
дастtrue
для "нашли" иfalse
для "не нашли".
The
~
для всех 4-х байтint
равно этой формуле-(N+1)
так
~0 = -(0+1) // -1 ~35 = -(35+1) // -36 ~-35 = -(-35+1) //34
The
~
оператор-это побитовый оператор дополнения. Целочисленный результат отinArray()
либо -1, когда элемент не найден, либо некоторое неотрицательное целое число. Побитовое дополнение -1 (представленное в двоичном виде как все 1 бит) равно нулю. Побитовое дополнение любого неотрицательного целого числа всегда ненулевое.таким образом,
!!~i
будетtrue
когда целое число " i " является неотрицательным целым числом, иfalse
когда "я" точно -1.отметим, что
~
всегда преобразует свой операнд в целое число; то есть он принудительно преобразует нецелые значения с плавающей запятой в целочисленные, а также нечисловые значения.
Тильда побитовая не-она инвертирует каждый бит значения. Как правило, если вы используете
~
на число, то его знак будет инвертирован, то 1 будет вычитаться.таким образом, когда вы делаете
~0
, вы получаете -1 (0 инвертировано -0, вычитание 1 равно -1).это по существу сложный, супер-микро-оптимизированный способ получения значения, которое всегда является логическим.
вы правы: этот код вернет
false
когдаindexOf
вызов возвращает -1, в противном случаеtrue
.как вы говорите, было бы гораздо разумнее использовать что-то вроде
return this.modifiedPaths.indexOf(path) !== -1;
The
~
оператор является побитовым оператором NOT. Это означает, что он принимает число в двоичной форме и превращает все нули в единицы и единицы в нули.например, число 0 в двоичном составляет
0000000
, в то время как -111111111
. Кроме того, 1-это00000001
в двоичном формате, в то время как -211111110
.
Я предполагаю, что это там, потому что это несколько символов короче (какие авторы библиотеки всегда после). Он также использует операции, которые занимают всего несколько машинных циклов при компиляции в машинный код (в отличие от сравнения с числом.)
Я согласен с другим ответом, что это перебор, но, возможно, имеет смысл в узком цикле (требуется оценка прироста производительности, хотя в противном случае может оказаться преждевременной оптимизацией.)