3

我有下面的代码,我试图在一个参数的帮助下执行一个函数。上面的参数告诉Javascript来在阵列上/串使得其指示执行的操作(例如ps阵列并且如果id参数为0 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:赋值中无效的左手边”。如果我从=左侧删除括号,它将起作用,除了它执行仅适用于后一个阵列(又名as)而不是前者(又名ps)的功能。

我知道我在这里做错了什么,错过了一个符号/一对括号或其他东西。我已经检查了operator precedence in Javascript,关于同一事件的其他问题,但都表明它应该起作用,因为操作员(我认为)是正确的,例如,条件的===,转让的简单的=等。最令我困惑的是三元运算符内的其他引用(本示例的右边部分,我的代码的其他部分)工作。

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

回答

3

您不能在作业的左侧使用? :。三元运算符表达式的值始终为的值,而不是的引用;编程语言人们通常使用的r值l值。您只能分配到的l值,但不能生成l值? :

“l”和“r”代表“左”和“右”并且与赋值运算符有关。当然,并非所有的语言都从右向左进行分配;音乐编程语言“查克”是一个反例。

如果你将值分配给一个对象的属性,你可以做这样的事情:

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

这是因为? :是一个子表达式是左手侧的判定的一部分分配。这没关系,因为外部[ ]表达式返回l值

+0

我不得不承认,这是最好的答案,只是因为它正好说明发生了什么,为什么我的做法是不正确的。我解决了这个问题,但没有使用“对象”(严格来说),而是通过将等式的右边部分分配给“虚拟数组”(名为_temp_),然后使_if(id === 0){ps = temp;} else {as = temp} _在我的函数结尾处。如果您提供了适用于我的特定代码的简单解决方案,那么您的答案将会非常完美,但即便如此,这也是最好的答案。谢谢。必须删除并重新发布我更正的评论,因为我无法编辑它。 –

2

表达式(id === 0 ? ps : as)返回psas的值。如果你想分配something的变量做这样的事情:

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

另一种方式是有条件通过计算成员访问环绕psas一个对象,并设置任一成员:

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

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

好的答案,解决方案导向,但它缺乏解释为什么会发生这种情况(Pointy的答案并不缺乏)。我不得不标记他的答案,因为我实际上明白我错在哪里。尽管如此,我还是给了你一个赞赏 - 谢谢。 –

1

你可以用一个数组和computed property names做一个destructuring assignment

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

+0

感谢您提供完全适合我的代码的解决方案。就像杰弗里的回答一样,这无疑是有帮助的,但并不能解释我错在哪里。虽然提出了你的意见。 –

+0

这只是一个答案,什么是可能的。你的问题已经被[Pointy](https://www.filecrypt.cc/Container/D24940861A.html)所描述,不需要重复。 –

+0

确实。你可以检查我的评论给Pointy,看看我如何解决它,而不使用额外的对象(临时数组除外)。 –

相关问题