大括号中的带连字符的变量名

Hyphenated Variable Names in Curly Brackets

我正在 Google Google https://codelabs.developers.google.com/codelabs/actions-1/#5 上完成 Google 助手/操作的 NodeJS 教程,代码如下:

app.intent('Location', (conv, {geo-city}) => {
  const luckyNumber = geo-city.length;
  // Respond with the user's lucky number and end the conversation.
  conv.close('Your lucky number is ' + luckyNumber);
});

Dialogflow 和我的 IDE 中的 linter 都不满意 {geo-city},但我找不到解决方法。我试过引号、反引号等,但没有任何乐趣。我无法更改变量名称,因为它是一个 Google AI 系统实体 (https://cloud.google.com/dialogflow-enterprise/docs/reference/system-entities)。

请问正确的处理方法是什么?

这是对象析构语法。当你这样做时,例如:

const func = ({ foo }) => console.log('foo is', foo);

...你告诉 JavaScript:func 将把一个对象作为参数,但我只对名为的对象的 属性 感兴趣foo,所以请把foo 属性的值放在一个名为foo的变量中,忽略其余的。

然而,虽然 geo-city 在 JavaScript 中是一个有效的 属性 名称,但它不是一个有效的变量名称(否则将无法判断它是一个变量还是如果您尝试从 geo 中减去 city)。解决这个问题的一种方法是只将对象作为参数:

const func = (obj) => console.log('foo is', obj.foo);

...或者,应用于您的代码:

app.intent('Location', (conv, obj) => {
  const luckyNumber = obj['geo-city'].length;
  // ...
});

但是解构很好,我们还有另一种方法让它发挥作用。当你解构一个对象时,你可以为变量提供另一个名称:

const func = ({ foo: valueOfFoo }) => console.log('foo is', valueOfFoo);

这甚至适用于像 geo-city 这样的 属性,但你必须将它放在引号中,如下所示:

app.intent('Location', (conv, {'geo-city': geoCity}) => {
  const luckyNumber = geoCity.length;
  // ...
});

您可以更改 Dialogflow 参数列表中的名称。虽然它使用基于实体类型的默认值,但您可以将其更改为任何您想要的。

例如,给定这个训练短语,它在训练短语中选择了城市名称,将其分配为 @sys.geo-city 类型,并为其指定默认名称 geo-city

您可以点击参数名称,对其进行编辑,并将其更改为`city。

那么,您的代码仅使用 city 作为参数名称。

app.intent('Location', (conv, {city}) => {
  const luckyNumber = city.length;
  // Respond with the user's lucky number and end the conversation.
  conv.close('Your lucky number is ' + luckyNumber);
});

如果您真的想将其命名为 "geo-city",您仍然可以将其用作参数名称。该函数的第二个参数只是一个以 Dialogflow 参数名称为键的对象,他们正在使用一些 JavaScript 语法糖来解构它。但你不必这样做。您可以使用类似

的代码
app.intent('Location', (conv, params) => {
  const luckyNumber = params['geo-city'].length;
  // Respond with the user's lucky number and end the conversation.
  conv.close('Your lucky number is ' + luckyNumber);
});