Подтвердить что ты не робот

Являются ли эти строки кода 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
4b9b3361

Ответ 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 может быть функцией.