数组赋值中的引用错误(左手赋值)
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-value 和 l-value。您只能分配给 l 值,但不能使用 ? :
.
生成 l 值
"l"和"r"代表"left"和"right",是相对于赋值运算符的。当然,并非所有语言都从右到左分配;音乐编程语言 "Chuck" 是一个反例。
如果您要为对象赋值 属性,您可以这样做:
someObject[foo == bar ? "x" : "y"] = whatever();
那是因为 ? :
是一个子表达式,它是确定赋值左侧的一部分。这没关系,因为外部 [ ]
表达式 returns 一个 l-value.
表达式 (id === 0 ? ps : as)
returns ps
或 as
的值。如果要将 something
分配给变量,请执行以下操作:
if (0 === id) ps = something;
else as = something;
另一种方法是围绕 ps
和 as
包装一个对象,并通过计算的成员访问有条件地设置任一成员:
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; }
我有以下代码,其中我试图在参数的帮助下执行函数。该参数告诉 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-value 和 l-value。您只能分配给 l 值,但不能使用 ? :
.
"l"和"r"代表"left"和"right",是相对于赋值运算符的。当然,并非所有语言都从右到左分配;音乐编程语言 "Chuck" 是一个反例。
如果您要为对象赋值 属性,您可以这样做:
someObject[foo == bar ? "x" : "y"] = whatever();
那是因为 ? :
是一个子表达式,它是确定赋值左侧的一部分。这没关系,因为外部 [ ]
表达式 returns 一个 l-value.
表达式 (id === 0 ? ps : as)
returns ps
或 as
的值。如果要将 something
分配给变量,请执行以下操作:
if (0 === id) ps = something;
else as = something;
另一种方法是围绕 ps
和 as
包装一个对象,并通过计算的成员访问有条件地设置任一成员:
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; }