数组赋值中的引用错误(左手赋值)

Reference error (left-hand asignment) in array assignment

我有以下代码,其中我试图在参数的帮助下执行函数。该参数告诉 Javascript 对它指示的 arrays/strings 执行操作(例如,如果 id 参数为 0,则 ps 数组和 properties 字符串,并且 as 数组和 attributes 字符串(如果 id 不是 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 这里。它在 (id === 0 ? ps : as) = 部分抛出一个 "Uncaught ReferenceError: Invalid left-hand side in assignment" 。如果我从 = 的左侧删除括号,它会起作用,除了它执行仅针对后一个数组(aka as)而不是前者(aka ps).

我知道我在这里做错了什么,缺少一个符号/一对括号或其他东西。我已经检查了 operator precedence in Javascript,关于同一问题的其他问题,但都表明它应该有效,因为运算符(我认为)是正确的,例如=== 用于条件,简单 = 用于赋值等。最让我困扰的是三元运算符中的其他引用有效(此示例的右侧部分,我代码的其他部分)。

那么...这个有什么问题吗?

您不能在赋值的左侧使用 ? :。三元运算符表达式的值始终是 value,而不是 reference;编程语言人们通常使用术语 r-valuel-value。您只能分配给 l 值,但不能使用 ? :.

生成 l 值

"l"和"r"代表"left"和"right",是相对于赋值运算符的。当然,并非所有语言都从右到左分配;音乐编程语言 "Chuck" 是一个反例。

如果您要为对象赋值 属性,您可以这样做:

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

那是因为 ? : 是一个子表达式,它是确定赋值左侧的一部分。这没关系,因为外部 [ ] 表达式 returns 一个 l-value.

表达式 (id === 0 ? ps : as) returns psas 的值。如果要将 something 分配给变量,请执行以下操作:

if (0 === id) ps = something;
else as = something;

另一种方法是围绕 psas 包装一个对象,并通过计算的成员访问有条件地设置任一成员:

const obj = {
    ps: [],
    as: [],
}

obj[0 === id ? 'ps' : 'as'] = something;

你可以做一个destructuring assignment with an array and the right assigned result with computed property names

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

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

getpsas(0);
getpsas(1);

console.log(ps);
console.log(as);
.as-console-wrapper { max-height: 100% !important; top: 0; }