var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Я видел это в ответ, и я никогда не видел его раньше.
Что это значит?
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Я видел это в ответ, и я никогда не видел его раньше.
Что это значит?
~
является побитным оператором, который переворачивает все биты в его операнде.
Например, если ваш номер был 1
, его двоичное представление IEEE 754 float (как JavaScript обрабатывает числа)...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
So ~
преобразует свой операнд в 32-битное целое число (побитовые операторы в JavaScript делают это)...
0000 0000 0000 0000 0000 0000 0000 0001
Если бы это было отрицательное число, оно было бы сохранено в 2 дополнениях: инвертируйте все биты и добавьте 1.
... и затем переворачивает все его биты...
1111 1111 1111 1111 1111 1111 1111 1110
Так что же его использовать? Когда можно когда-нибудь использовать его?
У него довольно много применений. Если вы пишете материал низкого уровня, это удобно. Если вы профилировали свое приложение и нашли узкое место, его можно было бы сделать более результативным, используя побитовые трюки (как один из возможных инструментов в гораздо большем пакете).
Это также (как правило) нечеткий трюк, чтобы превратить indexOf()
найденное возвращаемое значение в правду (при этом не найденное как ложное), и люди часто используют его для своего побочного эффекта усечения чисел до 32 бит (и отбрасывая его десятичное место удваивая его, фактически так же, как Math.floor()
для положительных чисел).
Я говорю неясно, потому что не сразу видно, для чего он используется. Как правило, вы хотите, чтобы ваш код четко сообщал другим людям, читающим его. Хотя использование ~
может показаться классным, оно, как правило, слишком умное для своего же блага.:)
Это также менее актуально сейчас, когда JavaScript Array.prototype.includes()
и String.prototype.includes()
. Они возвращают логическое значение. Если ваша целевая платформа поддерживает ее, вы должны предпочесть это для тестирования на наличие значения в строке или массиве.
Использование его перед выражением indexOf()
эффективно дает вам правдивый/фальшивый результат вместо возвращаемого числового индекса.
Если возвращаемое значение -1
, то ~-1
равно 0
, потому что -1
- это строка из всех 1 бит. Любое значение, большее или равное нулю, даст ненулевой результат. Таким образом,
if (~someString.indexOf(something)) {
}
приведет к выполнению кода if
, когда "something" находится в "someString". Если вы попытаетесь использовать .indexOf()
в качестве логического напрямую, это не сработает, потому что иногда оно возвращает ноль (когда "что-то" находится в начале строки).
Конечно, это тоже работает:
if (someString.indexOf(something) >= 0) {
}
и это значительно менее загадочно.
Иногда вы также увидите следующее:
var i = ~~something;
Использование оператора ~
в два раза быстрее, чем это быстрый способ преобразования строки в 32-разрядное целое. Первый ~
выполняет преобразование, а второй ~
переворачивает бит обратно. Конечно, если оператор применяется к тому, что не может быть преобразовано в число, вы получаете NaN
в результате. (edit — на самом деле это второй ~
, который применяется сначала, но вы получаете идею.)
~indexOf(item)
появляется довольно часто, и ответы здесь велики, но, возможно, некоторым людям просто нужно знать, как их использовать и "пропустить" теорию:
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
~
Поименованный оператор NOT, ~x
примерно такой же, как -(x+1)
. Это проще понять, вроде. Итак:
~2; // -(2+1) ==> -3
Рассмотрим -(x+1)
. -1
может выполнить эту операцию для создания 0
.
Другими словами, ~
, используемый с диапазоном значений числа, приведет к значению falsy
(принуждение к false
от 0
) только для входного значения -1
, в противном случае любой другой truthy
значение.
Как известно, -1
обычно называют дозорным значением. Он используется для многих функций, которые возвращают значения >= 0
для успеха и -1
для отказа в C
языке. Какое же правило возвращаемого значения indexOf()
в JavaScript.
Обычно проверяется наличие/отсутствие a substring
в другом string
таким образом
var a = "Hello Baby";
if (a.indexOf("Ba") >= 0) {
// found it
}
if (a.indexOf("Ba") != -1) {
// found it
}
if (a.indexOf("aB") < 0) {
// not found
}
if (a.indexOf( "aB" ) == -1) {
// not found
}
Однако было бы проще сделать это через ~
, как показано ниже
var a = "Hello Baby";
~a.indexOf("Ba"); // -7 -> truthy
if (~a.indexOf("Ba")) { // true
// found it
}
~a.indexOf("aB"); // 0 -> falsy
!~a.indexOf("aB"); // true
if (!~a.indexOf( "aB" )) { // true
// not found
}
Для тех, кто рассматривает использование тильд-трюка для создания правдивого значения из результата indexOf
, он более явчен и имеет меньше магии вместо этого использовать includes
на String
.
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
Обратите внимание, что это новый стандартный метод с ES 2015, поэтому он не будет работать на старых браузерах. В тех случаях, когда это имеет значение, рассмотрите возможность использования String.prototype.includes polyfill.
Эта функция также доступна для массивов с использованием того же синтаксиса:
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false
Вот вам Array.prototype.includes polyfill, если вам нужна более старая поддержка браузера.