"This proposal augments the default operator by adding syntax to avoid 
accessing a missing property, specifically ?. for getting and setting a 
property from a reference base that might be undefined or null:" [1]

The specified semantics of proposal actually does more than "avoid accessing a 
missing property".  It also avoids accessing a property of a missing object.  
For example,

function f() {
   var foo;                   //oops, I forgot to write the initializer 
expression
   return foo?.bar;    //returns undefined because foo evaluates to undefined.  
foo.bar  would throw
}

This seems slightly and possibly significantly different from a situation like:

function f(foo={ }) {
   return foo?.bar;    //returns value of foo.bar or undefined if property bar 
does not exist, just like foo.bar
}

In particular, it has the affect of possibly propagating the detection of a 
simple editorial error like a forgotten initializer further from its place of 
occurrence.

At the least, this behavior probably should be clarified in the description

The inability to use  ?.  meaningfully in a function call context would seem to 
make this a only half useful feature.  I suspect many people will initially try 
to write something like
     foo?.bar()
with the expectation that the call will be skipped if  bar doesn't exist.

These may be an alternative semantics that might address both of the above 
issues.  Consider:

The semantics of ?. could be defined in terms of a new Reference variant (a 
Conditiional Reference):
Let baseReference be the result of evaluating MemberExpression.
If Type(baseReference) is Reference and IsConditionalReference(baseReference) 
is true, then let baseValue be GetUnconditionalValueOrMissing(baseReference)
Else let baseValue be GetValue(baseReference).
If baseValue is null or undefined, then throw a TypeError exception.
Let propertyName be the result of evaluating IdentifierName.
If the syntactic production that is being evaluated is contained in strict mode 
code, let strict be true, else let strict be false.
Return a value of type Conditional Reference whose base value is baseValue and 
whose referenced name is propertyName, and whose strict mode flag is strict.
Missing is an internal value that designates an attempt to access a missing 
value.

GetUnconditionalValueOrMissing(R) where R is a Reference is defined as
Let value be GetValue(R).
If value is null or undefined then if IsConditionalReference(R) is true hen 
return Missing.
Return value.

and GetValue would get the following new steps:

2.5 If IsConditionalReference(V) is true then If base is Missing then  then 
return undefined.

Function call semantics  (11.2.3) could then be modified with the existing step 
2 replaced with

2.1 Let func be GetUnconditionalValueorMIssing(ref).
2.2 If func is MIssing, then return undefined.

With these changes, the following would evaluate to undefined:
    var foo ={},  foo2;
    foo?.bar()
but
     foo.bar();
would throw.

But note that both
   foo2.bar()
   foo2?.bar()
would throw reference error exceptions because of line 4 of the ?. semantics n 
(and the existing .). In other words, a variable reference that resolves to 
undefined or null when used as a base of ?. doesn't be a pass.

However, the two above changes a separable with want one, but not the other. 

Allen

[1]: http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator 
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to