Ответ 1
~
является побитовым оператором. Он инвертирует бит своего операнда. !
является логическим оператором. Побитовый оператор не возвращает 0
при применении к -1
, что возвращает indexOf
, когда значение не найдено в массиве. Поскольку 0
оценивается как false
, дважды отрицая его, он просто возвращает false
(булево значение, а не числовое):
var index = _sessions.indexOf("_SID_5");
console.log(~index); // 0
console.log(!~index); // true
console.log(!!~index); //false
Побитовый оператор не вернет значение меньше 0 для любого другого возможного значения, возвращаемого indexOf
. Поскольку любое другое значение будет оцениваться как true
, это всего лишь сокращенный метод (вид... они оба одинакового количества символов!) Проверки того, существует ли элемент в массиве, а не явно сравнивается с -1
if (_sessions.indexOf("_SID_5") > -1) {
// This would work the same way
}
Обновление
Что касается производительности этого, он появляется (по крайней мере, в Chrome) как минимум медленнее, чем более распространенное сравнение с -1
(которое само немного медленнее, чем сравнение с 0
).
Здесь тестовый пример, и здесь результаты:
Обновление 2
Фактически, код в вашем вопросе может быть сокращен, что, возможно, было тем, что пытался сделать автор. Вы можете просто удалить !!
, так как ~
всегда будет иметь значение 0
или ниже (и 0
- единственное значение, которое будет оцениваться как false
):
if (~_sessions.indexOf("_SID_5")) {
// This works too
}
Однако в несколько иной ситуации было бы целесообразно добавить в операторы !
. Если бы вы сохранили результат побитового оператора в переменной, это было бы числовым значением. Применяя логический оператор not, вы получаете логическое значение (и его повторное использование гарантирует, что вы получите правильное логическое значение). Если по какой-то причине вам требуется логическое значение над числовым, это немного лучше (но вы все равно можете использовать обычное сравнение с -1
или 0
):
var inArray = !!~_sessions.indexOf("_SID_5");
console.log(typeof inArray); // boolean