Search code examples
javascriptarraysvariable-assignmentoperator-keywordternary

Reference error (left-hand asignment) in array assignment


I have the following code, where I'm trying to execute a function with the help of a parameter. The parameter tells Javascript to perform the operations on the arrays/strings that it indicates (e.g. ps array and properties string if the id parameter is 0, and as array and attributes string if the id is other than 0):

var properties = "apple=fruit";
var attributes = "carrot=vegetable banana=fruit cherry=fruit fruit";
var ps = [];
var as = [];

function getpsas(id)
  {
  (id === 0 ? ps : as) = (id === 0 ? properties : attributes).split(" ").map
    (
    function(element)
      {
      var eqlpos = element.lastIndexOf("=");
      return {name: element.substr(0, eqlpos), type: element.substr(eqlpos + 1)};
      }
    ).filter
      (
      function(element)
        {
        return (/^(vegetable|fruit)$/.test(element.type));
        }
      );
  }

getpsas(0);
getpsas(1);

console.log(ps);
console.log(as);

, Fiddle here. It throws a "Uncaught ReferenceError: Invalid left-hand side in assignment" at the (id === 0 ? ps : as) = part. If I remove the brackets from the left side of = it works, except that it executes the functions that follow only for the latter array (aka as) and not for the former (aka ps).

I know I'm doing something wrong here, missing a sign / pair of brackets or something. I've checked the operator precedence in Javascript, other questions on the same matter, but all indicates that it should work, since the operators are (I think) correct, e.g. === for conditionals, simple = for assignment, etc. What bothers me the most is that other references inside ternary operators work (the right part of this sample, other parts of my code).

So ... what is wrong with this one?


Solution

  • You cannot use ? : on the left-hand side of an assignment. The value of a ternary operator expression is always a value, not a reference; programming language people usually use the terms r-value and l-value. You can only assign to an l-value, but you cannot produce an l-value with ? :.

    The "l" and "r" stand for "left" and "right" and are relative to the assignment operator. Not all languages do assignment from right to left of course; the music programming language "Chuck" is a counter-example.

    If you're assigning a value to an object property, you can do something like this:

    someObject[foo == bar ? "x" : "y"] = whatever();
    

    That's because the ? : is a subexpression that is part of the determination of the left-hand side of the assignment. That's OK because the outer [ ] expression returns an l-value.