if (n === null && o !== null || // non null -> null
n !== null && o === null || // null -> non null
(n !== null && o !== null && // both non null, check members
(n.age !== o.age ||
n.name !== o.name))) {
triggerEvent();
}
Давайте разберем это вниз (я использовал n
и o
Shorthands, чтобы соответствовать больше на линии, чтобы сделать его легче увидеть, что гои нг на - не предполагая использовать эти лаконичные конвенции):
n === null && o !== null ||
n !== null && o === null
Это выражение можно упростить до просто: n !== o
.
Это работает, потому что, если он является нулевым, а не другим, выражение будет оценивать true. Если объекты указывают на идентичные адреса памяти, это также вернет false (это хорошо, поскольку их поля также совпадают, и мы не хотим запускать события в этом случае).
Так что заставляет нас здесь:
if (n !== o ||
((n !== null && o !== null) &&
(n.age !== o.age || n.name !== o.name))) {
triggerEvent();
}
Для упрощения за это, как правило, требуют введения функции. Было бы неплохо, если бы вы делали такие вещи, чтобы обеспечить метод равенства для этих состояний, который сравнивает эти поля age
и name
. Это также сделает код менее подверженным ошибкам, если вы добавите новые состояния.
Null Сменный Trick
Другой трюк, который иногда может быть полезно при стоимости нескольких циклов является нулевой своп между парами. Пример:
// if 'a' is null:
if (!a)
{
// swap it with 'b'.
a = [b, b = a][0];
}
// Now if 'a' is still null, both values are null.
// If 'b' is not null, both values are not null.
Мы можем использовать его в приведенном выше коде следующим образом:
local state1 = oldState
local state2 = newState
if (!state1)
state1 = [state2, state2 = state1][0];
if (state1) {
// If only one of these is not null or their fields don't match:
if (!state2 || state1.age !== state2.age || state1.name !== state2.name) {
triggerEvent();
}
}
Много упрощает ли это или complexifies будет основываться на том, как часто вы используете этот вид лаконичным свопинга одно- вкладыш. Если это очень редко, это может только добавить к путанице.Но этот метод подкачки позволяет вам писать немного более подробный код в обмен на код, который потенциально более прост и не слишком сильно подавляет ваш мозговой стек (иногда более простой код предпочтительнее какой-то очень сложной вещи, которая требует вложенного синтаксического анализа).
Сверху моей головы вы можете попробовать использовать JSON.stringify на обоих объектах и сравнить их просто как строки. – 1cgonza
Вы можете попробовать это 'if ((! NewState || newState) && (! OldState || oldState) && (newState && oldState)) { if (newState.name! == oldState.name) { triggerEvent() ; } } ' –
@ 1cgonza Но' 'JSON.stringify' говорит что-нибудь о порядке ключей в' Object'? И даже в ES6, где ключи упорядочены, вы действительно хотите, чтобы '{a: 1, b: 2} и' {b: 2, a: 1} 'были неравными? –