Я пытаюсь реализовать XOR в JavaScript следующим образом:
// XOR validation
if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) ||
(!isEmptyString(firstStr) && isEmptyString(secondStr))
{
alert(SOME_VALIDATION_MSG);
return;
}
Существует ли лучший способ сделать это в JavaScript?
Спасибо.
Я предполагаю, что вам нужен логический XOR, поскольку в javascript уже есть побитовый (^) :)
Я обычно использую простой троичный оператор (один из редких случаев, когда я его использую):
if ((isEmptyString(firstStr) ? !isEmptyString(secondStr)
: isEmptyString(secondStr))) {
alert(SOME_VALIDATION_MSG);
return;
}
Edit:
работаю над решением @Jeff Meatball Yang solution
if ((!isEmptyString(firstStr) ^ !isEmptyString(secondStr))) {
alert(SOME_VALIDATION_MSG);
return;
}
вы отрицаете значения, чтобы преобразовать их в булевы, а затем применяете побитовый оператор xor. Возможно, оно не такое удобное в обслуживании, как первое решение (а может, я слишком привык к первому)
Посмотрите это объяснение различных реализаций XOR в javascript.
Просто подытожим некоторые из них прямо здесь:
if( ( isEmptyString(firstStr) || isEmptyString(secondStr)) && !( isEmptyString(firstStr) && isEmptyString(secondStr)) ) {
alert(SOME_VALIDATION_MSG);
return;
}
OR
if( isEmptyString(firstStr)? !isEmptyString(secondStr): isEmptyString(secondStr)) {
alert(SOME_VALIDATION_MSG);
return;
}
OR
if( (isEmptyString(firstStr) ? 1 : 0 ) ^ (isEmptyString(secondStr) ? 1 : 0 ) ) {
alert(SOME_VALIDATION_MSG);
return;
}
OR
if( !isEmptyString(firstStr)!= !isEmptyString(secondStr)) {
alert(SOME_VALIDATION_MSG);
return;
}
Цитирую по этой статье:
К сожалению, в JavaScript нет логического оператора XOR.
Вы можете "эмулировать" поведение оператора XOR с помощью чего-то вроде:
if( !foo != !bar ) {
...
}
В статье по ссылке обсуждается пара альтернативных подходов.
Вы можете напрямую использовать побитовый оператор XOR ( ^
):
if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) {
// ...
}
Он будет работать для вашего примера, поскольку логические значения true
и false
равны преобразованы в 1
и 0
, потому что побитовые операторы работают с 32-битными целыми числами.
Это выражение также вернет либо 0
, либо 1
, и это значение будет возвращено к логическому с помощью оператора if
.
Вы должны знать о приведении типов, которое происходит с указанным выше подходом. Если вы ищете хорошую производительность, я бы не рекомендовал вам работать с поразрядными операторами, вы также можете сделать простую функцию, используя только логические операторы:
function xor(x, y) {
return (x || y) && !(x && y);
}
if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) {
// ...
}
Вы делаете XOR булевых значений, который легко смоделировать в побитовый XOR (который есть в Javascript):
var a = isEmptyString(firstStr) ? 1 : 0;
var b = isEmptyString(secondStr) ? 1 : 0;
if(a ^ b) { ... }
В Javascript нет логического оператора XOR, поэтому ваша конструкция кажется правдоподобной. Если бы это были числа, то можно было бы использовать ^, т.е. побитовый оператор XOR.
cheers
XOR просто означает «отличаются ли эти два логических значения?». Следовательно:
if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) {
// ...
}
!!
предназначены только для того, чтобы гарантировать, что оператор ! =
сравнивает два настоящих логических значения, поскольку предположительно isEmptyString ()
возвращает что-то еще (например, null
для false , или сама строка для истины).
Как указывали другие, логический XOR такой же, как не-равно для логических значений, поэтому вы можете сделать это:
// XOR validation
if( isEmptyString(firstStr) != isEmptyString(secondStr) )
{
alert(SOME_VALIDATION_MSG);
return;
}