Подтвердить что ты не робот

Что делает ~ ~?

Я читал этот пост в блоге, в котором упоминалось использование:

!!~ 

Я понятия не имею, что это делает? сначала я думал, что это даст ошибку, но код ниже работает:

var _sessions = [
    "_SID_1",
    "_SID_2",
    "_SID_3",
    "_SID_4"
];

if(!!~_sessions.indexOf("_SID_5")) {
    console.log('found');
} else {
    console.log('!found');
}

выход:

node test.js 
!found
4b9b3361

Ответ 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).

Здесь тестовый пример, и здесь результаты:

enter image description here

Обновление 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

Ответ 2

Дональд Кнут: "[...] преждевременная оптимизация - корень всего зла"

Для удобства чтения используйте

.indexOf !== -1

Ответ 3

Это хорошо объясняет:

Оператор тильды в Javascript

Смешение двух операторов NOT может привести к некоторым интересным результатам:

! ~ (-2) = false

! ~ (-1) = true

! ~ (0) = false

! ~ (1) = false

! ~ (2) = false

Итак, это просто проверяет, равно ли значение равно -1 или нет, а indexOf возвращает -1, если он не находит совпадение