A partial archive of discourse.wicg.io as of Saturday February 24, 2024.

The ?. get-member-if-not-null-or-undefined-else-bail

phistuck
2016-11-24

Borrowing from a recent (well, 2014) C# 6.0 addition, the null propagation operator, I propose the get-member-if-not-null-or-undefined-else-bail syntax - ?., which can shorten a lot of code - return object?.member?.innerMember It is an almost* equivalent syntactic sugar for - return object && object.member && object.member.innerMember (*This obviously checks for more than just null or undefined and can be problematic, but authors generally knows they are dealing with members that are objects and not other truthy values)

Or the longer -

if (object)
{
 if (object.member)
 {
  return object.member.innerMember;
 }
}
MT
2016-11-24

Nice idea. An alternative solution would be to have a sort of built-in function that would just suppress errors during trying to access submembers of its argument, for example:

lastObjectMember(object.member.innerMember);
phistuck
2016-11-24

Kind of like the typeof magic (you can reference non existent variables in typeof, but using them otherwise, even in if (nonExistentVariable) would throw)? I think I prefer less magic…

stuartpb
2016-11-25

The trouble I have with this is that I’d want it to also apply with [] indexing (there are just as many constructions where this is useful for array indexing and/or variable indices), but parsing a partial construction like object?['member'/*...*/ would be syntactically ambiguous with value ? [array,members,ifTrue] : somethingElse without requiring a non-trivial amount of lookahead for a matching :, if I’m not mistaken.

Perhaps the operator could be .?property, and the matching indexing operator could be [?index] - just switching the character order from how C# did it?

phistuck
2016-11-25

Yep, that looks great.

stuartpb
2016-11-25

It’s worth noting that the (non-magic) version of this is already simple enough to implement yourself, using a slightly different signature (assuming none of the properties have . in the name):

function lastObjectMember(node, route) {
  route = route.split('.');
  while (node !== null && node !== undefined && route.length) {
    node = node[route.shift()];
  }
  return node;
}

/* usage: */

lastObjectMember(object,'member.innerMember');
phistuck
2016-11-25

Yes, but that adds a considerable amount of overhead.

stuartpb
2016-11-25

Eh, if you go one step further and change the signature to take a constructed array directly (and the implementation to use an iterator instead of shift()), it’s really not all that much more overhead than the logic that would be loaded by the VM - they’re both just a small constant stack allocation factor followed by an O(n) list traversal.

phistuck
2016-11-25

I disagree. I do not think the virtual machine logic would add so much more overhead. It already does it with the && way. ?. will have even less checks to worry about. https://jsperf.com/member-null-checks shows a considerable difference.

Then again, I never built, developed or maintained a virtual machine. :slight_smile:

phistuck
2017-01-30

Someone proposed it recently to TC39! Stage 1 (no GitHub explainer yet) -

Babel plugin (conforms to a different specification, though, but close) -

phistuck
2019-08-07

Stage 3 and a Chrome intent. Woo hoo, so close!

9pfs1
2022-02-25

If I’m not mistaken, this has been implemented.

phistuck
2022-02-26

Yes :slight_smile: