Двойные восклицательные знаки?

Возможный дубликат:
Что !! (не нет) оператор в JavaScript?
Что это !! оператор (двойной восклицательный знак) означает в JavaScript?

Итак, я отлаживал некоторый код и наткнулся на это:

var foo.bar = 0; // this is actually passed from another function, adding it for context

function(foo) {
    var someVar = !!foo.bar;

    if (foo.bar) {
      // ..stuff happens
    } else {
      // .. something else happens
    }
}

Хорошо, мои вопросы в чем смысл !! ? Все, что делает, это делает 0 === false.

  1. Есть ли польза от использования этого по сравнению с boolean(foo.bar)?

  2. foo.bar может быть оценен в if как есть, потому что 0 === false уже, так зачем проходить преобразование? (someVar больше нигде не используется)

Ответ 1

Это преобразует значение в логическое значение и обеспечивает логический тип.

"foo"      // Evaluates to "foo".
!"foo"     // Evaluates to false.
!!"foo"    // Evaluates to true.

Если foo.bar пропущен, то это может быть не 0, а какое-то другое ложное значение. Смотрите следующую таблицу истинности:

Таблица правды для JavaScript

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

Источник: Даг Крокфорд

Javascript также становится очень странным, когда дело доходит до значений NaN. И это единственный случай, когда я могу придумать, где это возможно! будет вести себя иначе, чем ===.

NaN   ===  NaN     //false
!!NaN === !!NaN    //true

// !!NaN is false

Ответ 2

Я думаю, что ответ заключается в том, что на самом деле нет особого смысла. Мы можем рассказать о том, как это произошло:

  • возможно, более ранняя версия функции, используемой someVar в нескольких местах, или способами, которые действительно выиграли от наличия true или false, поэтому это имело больше смысла.
  • Возможно, тот, кто написал эту функцию, так привык использовать !! для преобразования в true/false, что он даже не заметил, что здесь не нужно.
  • Возможно, человек, который написал функцию, считает, что каждому вычислению (в данном случае, логическому преобразованию) должно быть присвоено значащее имя, назначая некоторую переменную его результату.
  • возможно, поскольку булево преобразование в JavaScript удивительно подвержено ошибкам (в том, что, например, new Boolean(false) является истиннозначным значением), человек, который написал функцию, чувствует, что он всегда должен выполняться явно, а не неявно — хотя эффект тот же самый; просто обратить внимание на него как на потенциальную ошибку.
    • это, конечно, предполагает, что человек, который написал эту функцию, думает о !! как "явное" логическое преобразование. Технически это не так. он использует одно и то же неявное логическое преобразование, которое if делает — но если вы привыкли к этой идиоме, то это означает явное преобразование.

но по моему субъективному мнению ни одна из этих причин не очень хорошая!

Ответ 3

Как указано выше, он заставляет объект с булевым типом. Вы можете сами убедиться:

(function typecheck() {
  var a = "a";
  var b = !a;
  var c = !!a;

  alert("var a = " + typeof(a) + "\n" +
        "var b = " + typeof(b) + "\n" +
        "var c = " + typeof(c));
})();

Если вы просто выполняете сравнения, преобразование просто сохраняет ваше принуждение типа позже.

FYI, следующие значения принудительно приводятся к FALSE в JavaScript:

  • ложь
  • 0
  • ""
  • NULL
  • undefined