Страницы

Поиск по вопросам

четверг, 19 декабря 2019 г.

JavaScript Двойное отрицание(!!) и побитовый оператор Тильда (~)

#javascript


Изучаю JavaScript. Задачка из учебника:
Напишите функцию checkSpam(str), которая возвращает true, если строка str содержит
„html“ или „css“, а иначе false.
Функция должна быть нечувствительна к регистру:

Ответ из учебника:



function checkSpam(str) {
  var lowerStr = str.toLowerCase();

  return !!(~lowerStr.indexOf('html') || ~lowerStr.indexOf('css'));
}

alert( checkSpam('hTml now') );
alert( checkSpam('free cSs') );
alert( checkSpam("more java") );




Вопросы:  


Меня путает наличие сразу !! и ~
Как читается строка return? "Если не найдено, то вернуть ..."
первый знак ! = Не, и приводим к логическому типу; дальше непонятки из-за ~ и второго
отрицания.
Вот мой вариант, он мне кажется понятнее:




function checkSpam(str) {
	var lowerStr = str.toLowerCase();
	return (lowerStr.indexOf('html') != -1 || lowerStr.indexOf('css') != -1);
}
alert( checkSpam('hTml now') );
alert( checkSpam('free cSs') );
alert( checkSpam("more java") );




Есть ли в данных вариантах разница и какой вид более предпочтительный?
    


Ответы

Ответ 1



Знак ! обозначает не. Если вы напишите return (~lowerStr.indexOf('html') || ~lowerStr.indexOf('css')), то оно просто выведет положение слов. Если вы введёте return !(~lowerStr.indexOf('html') || ~lowerStr.indexOf('css')), но оно выведет true/false, при том, что false выведется, если слово было найдено А когда вы вводите два !!, то оно выведет true, там где было false и наоборот Знак ~ возвращает значение -(число + 1). Т.е. в вашем случае, если положение равно -1, то она выводит 0 и при этом в условии выводится false, а если другое любое число, то это true

Ответ 2



Вы столкнулись с "магией операторов". В данном случае операторы применяются для следующего: Оператор ~ возвращает 0 для -1 и не 0 для всего остального. Поэтому в булевом контексте оператор ~ делает почти то же самое, что и сравнение != -1. Оператор !! (на самом деле это два оператора), который вы правильно назвали двойным отрицанием, преобразует любое значение в булево. Этот оператор нужен только потому что оператор ~ возвращает число, если бы там было сравнение - то и двойное отрицание бы не понадобилось. Таким образом, вы совершенно правильно написали return (lowerStr.indexOf('html') != -1 || lowerStr.indexOf('css') != -1);. Ваш вариант делает в точности то же самое, что и строка из учебника, только написан понятнее. Можно даже убрать скобки: return lowerStr.indexOf('html') != -1 || lowerStr.indexOf('css') != -1; Именно так и надо писать если ваш код будет читать кто-то, кроме вас самих. Если же вы пишите так называемый "write-only" код - иногда имеет смысл использовать "магические" сокращения, коли это ускоряет его написание.

Комментариев нет:

Отправить комментарий