Earlier quoted context omitted.
It's nice for situations where you want to access a deeply nested prop, and you only care whether the whole path is there or not. Saves you having to add a seperate check for every level of the hierarchy. e.g. You can do: foo?.bar?.baz || "default"; Rather than: (foo && foo.bar && foo.bar.baz) || "default"; Agree that developers can be careful about nullability (in fact I pulled someone up on this in a code review ea…
The problem is that if you find yourself needing deep accessors, something is very wrong with your scopes. You are reaching across many levels of concerns which is a code smell. So, by making it “nice” you are making a code smell less smelly, which feels good in the moment, at the syntax level, but makes your code worse at the architecture level. This is roughly the story for all of ES6... make it “nice” to work with…
I'm not sure I agree with that statement in all scenarios. For code you control, sure.
But there are many APIs that return very deeply nested structures that are inconsistent in their shape. That, in my view, is the most common place devs will need deep accessors where parts may be null/undefined somewhere in between the root object and the key they are trying to access.
Sure, they could write functions that, similar to get in lodash, expose just the values needed, at which point chaining wouldn't be needed at all in the code that deals with that value. Or it could be serialized into a class object, but again, the chain would be dealt with in the serialization. At some point, the chain needs to be dealt with and often the JSON structures from APIs are not something that's always under our control.