Отрицание (!) перед выражением
приводит значение выражения к boolean, а затем инвертирует его. Это часто встречающаяся конструкция в JS. Это документированное и однозначное поведение.
Часто можно встретить так же двойное отрицание !! перед выражением. Двойное отрицание направлено на приведение выражения к чистому Boolean.
Отрицание (!) так же можно заменить на конструкцию типа (выражение) != true или (выражение) == false. Все эти конструкции приводят проверяемое выражение к Boolean. Такое поведение языка называется "неявное приведение".
Ниже идёт небольшое исследование (провёл только что для себя из интереса) и тема для холивара.
Несмотря на очень широкое распространение, использование неявное приведение типов считается порочной практикой в мире программирования, так как требует от программистов особого внимание к особенностям языка, затрудняет свободное чтение кода и в целом склоняет программиста к ошибкам.
Но "хорошо" или "плохо" ли использовать отрицание перед выражение - это непростой вопрос, на который не существует однозначного ответа. Есть "эталонная" книга по лучшим практикам в JS:
Javascript: The Good Parts Дугласа Крокфорда. Несмотря на многие спорные утверждения в ней, на эту книгу принято ссылаться как на истину в последней инстанции. Так вот, Крокфорд однозначно требует использование строгого равенства (операторы "===" и "!==") в пользу нестрого (операторы "==" и "!="). И многие компании с удовольствием его поддерживают и даже вводят ограничение на использование нестрогого равенства на уровне линтера. Но, к сожалению, Крокфорд ничего не сказал про оператор отрицания, который, по сути, тоже является нестрогим неравенством, явно запрещенным лучшими практиками. Раз ни Крокфорд, ни какой-либо другой влиятельный гуру ничего не сказали про отрицание, его продолжают использовать, радоваться простоте и страдать от неявных ошибок.
Лично для себя выбрал такую тактику: использую отрицание там где явно имею дело с логическими выражениями (пример привести не могу) и строгое равенство когда имею дело с функциями. В вашем случае, скорее всего, запись имела бы вид return /^[ \\t]*$/s.test(r) === false; . Почему так? Потому что функции регулярных выражений имеют свойство возвращать чёрт знает что и хочется пожалеть девелопера, который почти наверняка споткнётся читая return ! /^[ \\t]*$/s.test(r); и полезет в документацию выяснять что именно возвращает функция test.
Такие дела.