Эквивалентны ли эти строки кода 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;
-игры
var c = a.b
6 ответов:
нет, они НЕ ОБЯЗАТЕЛЬНО РАВНЫ всегда, если 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);
эти заявления логически эквивалентны.
Это было сказано, и как упоминалось в еще один ответ, если
a.b
имеет побочные эффекты, заявления не приведут в таком же положении программы.Это может быть легко очевидно в виде
var c
имеющие различное значение в зависимости от того, какие из этих операторов выполняются, или более скрытые, еслиa.b
изменяет что-то в другом месте программа.рефакторинг
как рефакторинг был обсужден, я коснусь его кратко. Как мы надеемся, выше было очевидно, что прямой рефакторинг будет не будут во всех сценариях. Тем не менее, я бы все равно рекомендовал рефактор того или иного рода.
две возможные ситуации, как я вижу их:
a.b
не имеет никаких побочных эффектов, прямое рефакторинг безопасноa.b
имеет скрытые побочные эффекты. Это представляет собой очень неясный, запутанный, и просто код. Она должна быть преобразована так, что все изменения, происходящие во время отчета понятно и очевидно в читатель (надеюсь, интуитивно так, а также поддерживается комментариями).
как уже указывал @potatopeelings, два возможных оператора не всегда эквивалентны, так как можно написать неясный код, который будет иметь разные результаты.
однако, если я вижу код, как
var c = (a.b !== null) ? a.b : null;
Я буду считать, что намерение кода
var c = a.b;
поэтому я изменю его, чтобы сделать код красивее. Если я буду негативно удивлен, то есть код не проходит фазы тестирования из-за этого изменения, то я постараюсь найти автор
a.b
с git виноват.Итак, мой ответ заключается в том, что эти два утверждения не эквивалентны, но должны быть эквивалентны в хорошо написанном коде.
ну, на самом деле даже не
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);
в то время как это присваивает
c
значение 1:Object.defineProperty(self, 'a', { get: function() { return c ^= 1; } }); var c = a; console.log(c);