Ошибка ссылки (левостороннее присвоение) в присваивании массива

У меня есть следующий код, где я пытаюсь выполнить функцию с помощью параметра. Параметр указывает Javascript выполнять операции над массивами / строками, которые он указывает (например, ps массив и properties строка, если id параметр равен 0, и 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);

Скрипач здесь. Выдает "Uncaught ReferenceError: Неверная левая сторона в назначении" в (id === 0 ? ps : as) = часть. Если я уберу скобки с левой стороны = это работает, за исключением того, что он выполняет функции, которые следуют только для последнего массива (иначе asа не для бывших (ака ps).

Я знаю, что я делаю что-то не так, пропуская знак / пару скобок или что-то в этом роде. Я проверил приоритет оператора в Javascript, другие вопросы по тому же вопросу, но все указывает на то, что он должен работать, так как операторы (я думаю) правильны, например === для условных, простых = для назначения и т. д. Больше всего меня беспокоит то, что работают другие ссылки внутри троичных операторов (правая часть этого примера, другие части моего кода).

Итак... что не так с этим?

3 ответа

Решение

Вы не можете использовать ? : на левой стороне задания. Значение выражения троичного оператора всегда является значением, а не ссылкой; В языке программирования люди обычно используют термины r-значение и l-значение. Вы можете назначить только l-значение, но вы не можете создать l-значение с ? :,

"L" и "r" означают "левый" и "правый" и относятся к оператору присваивания. Конечно, не все языки выполняют задание справа налево; язык программирования музыки "Чак" является контрпримером.

Если вы присваиваете значение свойству объекта, вы можете сделать что-то вроде этого:

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

Это потому что ? : является подвыражением, которое является частью определения левой части назначения. Это нормально, потому что внешний [ ] выражение возвращает значение l.

Выражение (id === 0 ? ps : as) возвращает значение либо ps или же as, Если вы хотите назначить something чтобы переменные сделали что-то вроде этого:

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

Другой способ - обернуть объект вокруг ps а также asи установите любой член условно через вычисленный доступ члена:

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

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

Вы могли бы сделать присвоение деструктурирования с массивом и правильно назначенный результат с вычисленными именами свойств.

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; }

Другие вопросы по тегам