Это оператор побитового НЕ. В этом случае используется логическое возвращаемое значение для indexOf
: методы indexOf
(массив, строка) возвращают -1, если совпадение не найдено, и позицию, если совпадение найдено. Позиция может быть и 0, конечно. Итак, используя побитовый оператор НЕ:
console.log(~-1); // 0
console.log(~0) // -1
console.log(~1) // -2
// and so on
Так как в JS 0
считается значением "Falsy", а любое другое число, кроме NaN
, является значением "Truthy", наличие ~zepto.qsa(parent, selector).indexOf(element)
вернет 0
, если элемент НЕ найден, и, следовательно, поток может иметь значение "Falsy". "значение в коде:
var isFound = ~zepto.qsa(parent, selector).indexOf(element);
if (isFound) {
// do something
}
Однако в этом случае я бы ожидал, что методы zepto вернут настоящее логическое значение, потому что это метод API. В этом случае я бы предпочел использовать просто:
match = zepto.qsa(parent, selector).indexOf(element) > -1;
Or
match = !!~zepto.qsa(parent, selector).indexOf(element);
Двойной !
используется для правильного логического представления: если indexOf
возвращает -1
, ~
преобразует его в 0
, затем первый !
в true
, а вторые в false
, это логическое значение, которое мы ожидаем для "не найдено" .
Побитовое НЕ также используется для некоторых других трюков, таких как этот:
var words = ["a", "b", "c", "b", "b"];
var frequency = words.reduce(function(freq, word) {
freq[word] = -~freq[word];
return freq;
}, {})
Этот код возвращает объект типа {a:1, b:3, c:1}
; в основном он подсчитывает частоту одного и того же строкового значения в массиве. Здесь побитовое НЕ используется с Унарный оператор отрицания, чтобы иметь инкрементный счетчик: так, если freq[word]
равно undefined
— потому что этого слова еще нет в «словаре» — тогда ~undefined
равно -1
, а при унарном отрицании становится 1
. В следующий раз у нас будет -~1
и, следовательно, - -2
, поэтому 2
; тогда -~2
будет 3
и так далее.
Побитовые операторы действительно полезны, но ими легче злоупотреблять. В некоторых случаях это необходимо (например, сдвиг вправо с нулевым заполнением в настоящее время это единственный способ в JS заменить ToUint32
), но это не так, и это может привести к затруднению чтения кода.
Но они определенно заслуживают того, чтобы о них знали.
person
ZER0
schedule
12.04.2013
indexOf
звонков. Если значение, возвращаемое изindexOf
, равно-1
(это означает, что оно не было найдено в коллекции/строке),~-1
равно0
... что логически совпадает сfalse
. Любое другое значение, возвращенное изindexOf
(больше -1),~value
будет истинным (то есть оно было найдено). Так что это простой способ поставитьindexOf
в сравнение - person Ian   schedule 12.04.2013