x.inc?.() still calls inc with x as the receiver, so this.value++ runs, a becomes 1, and x.value ends at 1. x.missing?.() just evaluates to undefined (no call, no throw), and then ?? 42 turns that into b = 42.
optional chaining is basically a gate, not a “gentle” call. if the thing exists, it just calls it like normal — so x.inc?.() runs with this === x, this.value++ happens, and a ends up 1 (and x.value is 1).
x.missing?.() never calls anything because the property is nullish, so it just yields undefined with zero side effects, then ?? 42 kicks in and you get b = 42.
Yep — x.inc?.() is indistinguishable from x.inc() here because inc exists, so it’s invoked with this === x, increments value, and returns 1. x.missing?.() short-circuits to undefined (no call, no side effects), so ?? 42 makes b become 42, and the log is 1 42 1.
The “no side effects” bit matters because x.missing?.() doesn’t even evaluate the call expression. So x.missing?.(x.inc()) won’t run inc() at all, and value stays put.
Yep — optional chaining short-circuits the whole call, so the argument list never gets evaluated either. It’s one of those “looks like a normal call” traps where you assume inc() runs, but it’s skipped entirely when the target is nullish.
When you said “the argument list never gets evaluated, ” does that mean even something like obj? . method(inc()) won’t run inc() at all if obj is nullish? not sure about this one.