воскресенье, 13 февраля 2011 г.

Javascript инверсия переменных

Довольно часто нужно сделать инверсию какой либо переменной. Например 0 в 1, true в false и так далее. Для этого мы ставим оператор ! и успешно двигаемся дальше. Но вернемся к спецификации
!a Логическое NOT Унарная операция. Возвращает true, если операнд ложен.
Это значит, что на инверсию нуля мы получаем true.
a=0
alert(!a) // true
В принципе ничего страшного скажете вы, но при следующих математических действиях с переменной true не может обрабатываться корректно.


Для решения данной проблемы нужно либо после инверсии делать преобразование типов через parseInt (в случае булевого значения достаточно использовать конструкцию !! ) или писать свой инвертор
function inv(a){
  if(a == 0 ){
    return 1;
  }
  else{
    return 0;
  }
}

Так же есть более продвинутые решения, которое посоветовал SHiSH:
++a%2
или
++a&1

В качестве объяснения как к первому так и ко второму примерам посмотрите на очередность выполнения действий: 
((++ a) & 1)

Набор тестов:
a = true
++a&1  // 0
a = false
++a&1  // 1
a = 0
++a&1  // 1
a = 1
++a&1  // 0
a = null
++a&1  // 1
a = undefined
++a&1  // 0 - Обратите внимание

Больше оптимизаций в следующей статье