Являются ли эти строки кода JavaScript эквивалентными?
Я нашел эту строку в JavaScript-коде.
var c = (a.b !== null) ? a.b : null;
Это сокращенное выражение if-else, но значение null присваивается, если оно равно null. Разве это не ВСЕГДА эквивалентно
var c = a.b
включая все случаи - исключения, null, undefined и т.д.
Другими словами, являются ли эти строки (всегда) эквивалентными?
var c = (a.b !== null) ? a.b : null;
-vs -
var c = a.b
Ответы
Ответ 1
Нет, они НЕОБХОДИМЫ EQUAL всегда, если b является получателем, который обновляет переменную. Плохая практика кодировать этот путь, хотя
var log = 0;
var a = {
get b() {
log++;
return log;
}
}
var c = (a.b !== null) ? a.b : null;
// outputs 2
console.log(c);
var log = 0;
var a = {
get b() {
log++;
return log;
}
}
var c = a.b;
// outputs 1
console.log(c);
Ответ 2
Эти утверждения логически эквивалентны.
При этом, как упоминалось в другом ответе, если a.b
имеет побочные эффекты, операторы не будут приводить к одному и тому же состоянию программы.
Это может быть легко очевидным в виде var c
, имеющего другое значение, зависящее от того, какое из этих операторов выполняется или более скрыто, если a.b
изменяет что-то в другом месте программы.
Рефакторинг
Как обсуждалось рефакторинг, я коснусь его кратко. Поскольку вышеупомянутое, как мы надеемся, стало очевидным, прямое рефакторинг не будет безопасным во всех сценариях. Однако я бы порекомендовал рефакторинг того или иного вида.
Две возможные ситуации, которые я вижу, следующие:
-
a.b
не имеет побочных эффектов, прямой рефакторинг безопасен
-
a.b
имеет скрытые побочные эффекты. Это представляет собой очень непонятное, запутанное,
и просто плохой плохой код. Он должен быть реорганизован таким образом, чтобы все
изменения, происходящие во время заявления, ясны и очевидны для
читателя (мы надеемся, интуитивно так, а также поддерживается комментариями).
Ответ 3
Как уже отмечалось в @potatopeelings, два возможных утверждения не всегда эквивалентны, поскольку можно написать неясный код, который будет иметь разные результаты.
Однако, если я вижу код, например
var c = (a.b !== null) ? a.b : null;
Я предполагаю, что намерение кода
var c = a.b;
поэтому я изменю его, чтобы сделать код более красивым. Если я буду отрицательно удивлен, то есть код не пройдет фазы тестирования из-за этого изменения, тогда я попытаюсь найти автора a.b
с git виной.
Итак, мой ответ заключается в том, что два утверждения не эквивалентны, но должны быть эквивалентны в хорошо написанном коде.
Ответ 4
Ну, на самом деле даже не
var c = (a !== null) ? a : null;
гарантированно эквивалентен
var c = a;
когда a
разрешается геттером или обработчиком прокси-сервера ES6 для глобального объекта.
Следовательно, например, присвойте c
значение 0:
Object.defineProperty(self, 'a', { get: function() { return c ^= 1; } });
var c = (a !== null) ? a : null;
console.log(c);
Ответ 5
Вы правы, var c = a.b
точно такой же, как var c = (a.b !== null) ? a.b : null;
Я предполагаю, что null
в тернарном операторе должен был быть чем-то кроме null
, значением по умолчанию, если вы это сделаете.
Ответ 6
Причиной этого смущающего нечетного синтаксиса является то, что a.b может быть пустой строкой ИЛИ undefined, и, видимо, пустая строка является допустимым.
Также обратите внимание: a.b может быть функцией.