A while back, I added support for the null conditional operator using ?.
syntax. I don't recall if I ever posted about it on the mailing list,
actually, so I thought I'd fully re-introduce it here because I actually
fixed some bugs recently, and I also added support for specifying property
names using strings with ?.[] syntax.

In JavaScript, this style of operator is called optional chaining. The same
feature was first added to AS3 in the AIR SDK by Harman. I wanted to be
sure that tooling that uses the Royale compiler for code intelligence, such
as vscode-as3mxml, could recognize the new syntax without reporting errors.
However, when I added this feature to Royale's AS3 compiler, I also
implemented it in JS for completeness.

This syntax works similarly to normal member access with the . operator.
Let's start with an example that uses normal member access to set the stage:

var a:Object = {b: "Royale is cool!"};
var x:Object = a.b;
trace(x); // Royale is cool!

The null conditional operator can be used in the same way, with the same
result:

var a:Object = {b: "Royale is cool!"};
var x:Object = a?.b;
trace(x); // Royale is cool!

However, things get different when the variable 'a' is null or undefined.
With normal member access, a run-time exception will be thrown when trying
to access a property of a null object:

var a:Object = null;
var x:Object = a.b; // exception!

With the null conditional operator, if the object is null (or undefined),
the result is null and no exception is thrown.

var a:Object = null;
var x:Object = a?.b;
trace(x); // null

Basically, this code...

var x:Object = a?.b;

...is equivalent to the following:

var x:Object = a == null ? null : a.b;

Null conditional operators can also be chained, and if any of the left
sides are null, then the result is null, with no exceptions thrown.

var x:Object = a?.b?.c?.d;

My recent addition is the ability to specify the property name using a
string (which JavaScript also supports).

First, let's see what normal dynamic access with brackets looks like:

var a:Object = {b: "Royale is cool!"};
var x:Object = a["b"];
trace(x); // Royale is cool!

Again, the new syntax works exactly the same when the left side is not null:

var a:Object = {b: "Royale is cool!"};
var x:Object = a?.["b"];
trace(x); // Royale is cool!

But when the left side is null, normal dynamic access throws an exception:

var a:Object = null;
var x:Object = a["b"]; // exception!

However, null conditional dynamic access returns null when the left side is
null or undefined:

var a:Object = null;
var x:Object = a?.["b"];
trace(x); // null

JavaScript also supports a null conditional method call. However, the
syntax that they chose for JavaScript would conflict with AS3's E4X
filtering syntax. So, unfortunately, if we ever want to add null
conditional method calls, we'll need to come up with new syntax.

I've added documentation for the null conditional operator here (but I
still need to add a section for the new null conditional dynamic access):

https://apache.github.io/royale-docs/features/as3/null-conditional-operator

--
Josh Tynjala
Bowler Hat LLC
https://bowlerhat.dev/

Reply via email to