Статьи

Охрана и операторы по умолчанию в Javascript

Все языки программирования с синтаксисом в стиле C имеют логические операторы для AND, OR и NOT. Это &&, || и! Соответственно. В Javascript способ, которым языки определяют логические операции, и значения, которые Javascript рассматривает как истинные или ложные, приводят к тому, что люди используют операторы AND и OR для ситуаций защиты и по умолчанию . Позволь мне объяснить.

Охрана и дефолт? Как так?

Вот краткий обзор того, как вы можете защитить значение:

var getUsername = function() {
return loggedIn && username;
}

Если пользователь еще не вошел в систему, loggedInбудет иметь значение false, и независимо от того, usernameчто было установлено, наша функция вернет false. Если loggedIntrue, то он перейдет к следующей переменной и вернется username.

Короче говоря, A && B вернет B, если A истинно (что Javascript считает истинным), иначе вернет A.

И вот как выглядит дефолт:

var MGFX = MGFX || {};

Я делаю это на вершине некоторых из моих классов Javascript. Я использую MGFX в качестве пространства имен для хранения всех моих классов, и чтобы убедиться, что он всегда существует, я объявляю это сверху. Если я ранее объявил var MGFX, то новый MGFX будет старым. Если нет, то это будет пустой объект.

Короче говоря, A || B вернет A, если A истинно, в противном случае по умолчанию используется значение B.

Подождите, это логические операторы, хотя …

Действительно, когда я впервые начал использовать это поведение, я понял, насколько это возможно. Не поймите меня неправильно, приятно иметь возможность объявить значение по умолчанию в 1 строке вместо 4. Но чтение этого заставляет меня думать, что должно возвращаться логическое значение .

Итак, чтобы утолить свое любопытство, я открыл этим утром Firebug и поиграл со всеми видами возможностей, наконец-то поняв, почему это действительно имеет смысл.

Javascript Истинный и Ложный

Стоит сначала узнать, что считается истинным и ложным в Javascript.

Все это будет иметь значение true (т.е. если вы поместите их в ifутверждение):

  • правда
  • Все номера кроме 0
  • Все непустые строки (включая «ложь» и «0»)
  • Массив (включая пустой: [])
  • Объект (включая пустой: {})

И это ложные значения:

  • ложный
  • 0
  • «»
  • значение NULL
  • NaN
  • не определено

Почему это имеет смысл

Чтобы понять, что происходит, вам нужно только понять, что делает оператор И или ИЛИ. Давайте возьмем AND. Чтобы операция И возвращала истину, обе части И должны по отдельности быть истиной. Таким образом, в Javascript первое значение оценивается, и только если оно истинно, оно пытается оценить следующее значение. Имеет смысл, так как второе значение не имеет значения, если первое ложно.

Что ж, тогда, действительно, вы могли бы избежать возврата оценки первой переменной, если она была ложной для всего оператора AND. И если бы это было правдой, оператор AND теперь зависит от оценки второго оператора и не заботится о первом (так как он истинен). Теперь возвращение второй оценки будет правильным ответом.

То же самое можно применить к ИЛИ. Если первое утверждение ложно, то результат ИЛИ полностью зависит от второго оператора. И если первое утверждение верно, ему не нужно второе утверждение для ИЛИ, чтобы быть истиной.

Единственная запутанная часть после осознания этого — значения, которые Javascript определяет как истинные. Или, скорее, то, что это в основном не приводит к булевому вычислению. Это оставляет их как есть.

Итак: 0 || «яблоко» возвращает «яблоко», потому что оно оценивается как истинное, и этого достаточно для Javascript.

Достижение оригинальных результатов

Мне нравится, как это работает. Но я хотел посмотреть, смогу ли я получить исходные результаты в тех случаях, когда я хочу получить логическое значение результата. Единственный способ сделать это — использовать двойное НЕ. Оператор NOT (!) В Javascript всегда возвращает логическое значение. Так что с помощью! даст мне логическое значение противоположного, а затем снова логическое значение истинного результата. Последний пример:

var iAreABoolean = !!(14 && "sean");    //returns !!("sean") which returns !(false) in turn gives me true.