如何在 JavaScript 对象字面量中使用变量作为键?

IT技术 javascript jquery variables properties object-literal
2020-12-25 22:57:22

为什么下面的工作?

<something>.stop().animate(
    { 'top' : 10 }, 10
);

而这不起作用:

var thetop = 'top';
<something>.stop().animate(
    { thetop : 10 }, 10
);

更清楚地说:目前我无法将 CSS 属性作为变量传递给 animate 函数。

6个回答

{ thetop : 10 }是一个有效的对象字面量。该代码将创建一个对象,其属性名为thetop10。以下两者相同:

obj = { thetop : 10 };
obj = { "thetop" : 10 };

在 ES5 及更早版本中,您不能在对象字面量中使用变量作为属性名称。您唯一的选择是执行以下操作:

var thetop = "top";

// create the object literal
var aniArgs = {};

// Assign the variable property name with a value of 10
aniArgs[thetop] = 10; 

// Pass the resulting object to the animate method
<something>.stop().animate(
    aniArgs, 10  
);  

ES6 ComputedPropertyName定义为对象字面量语法的一部分,它允许您编写如下代码:

var thetop = "top",
    obj = { [thetop]: 10 };

console.log(obj.top); // -> 10

您可以在每个主流浏览器的最新版本中使用这种新语法。

我明白!谢谢!这不应该也适用于 eval 吗?我的意思是它目前在我的示例中不起作用,但我认为它应该...... :-)
2021-02-06 22:57:22
@Marcel:eval()在动态属性名称的对象文字中不起作用,你只会得到一个错误。不仅如此,而且eval()真的不应该用于此类事情。有一篇关于正确和不正确使用的优秀文章evalblogs.msdn.com/ericlippert/archive/2003/11/01/53329.aspx
2021-02-06 22:57:22
@AndyE 考虑使用更具体的时间更新“最近版本”和“当前 IE TP”,例如“版本晚于 XXX”或“2014-mm 之后”(我会自己进行更改,但我不知道什么是好的值将是。
2021-02-09 22:57:22
很好的解决方案,但为什么你知道这么多,甚至阅读整个规范都无法理解:(
2021-02-16 22:57:22
对于 ES6,如果键为空/未定义,是否有办法忽略该属性?例如,在 中{[key] : "value"},如果键为空,它会给出{ null: "value"},而我希望结果是{}
2021-02-28 22:57:22

使用ECMAScript 2015,您现在可以使用括号表示法直接在对象声明中执行此操作: 

var obj = {
  [key]: value
}

wherekey可以是返回值的任何类型的表达式(例如变量)。

所以这里你的代码看起来像:

<something>.stop().animate({
  [thetop]: 10
}, 10)

thetop用作键之前将在哪里评估。

ES5 引用说它不应该工作

注意:ES6 的规则已更改:https ://stackoverflow.com/a/2274327/895245

规范:http : //www.ecma-international.org/ecma-262/5.1/#sec-11.1.5

物业名称:

  • 标识符名称
  • 字符串字面量
  • 数字文字

[...]

生产 PropertyName : IdentifierName 的评估如下:

  1. 返回包含与 IdentifierName 相同的字符序列的 String 值。

生产 PropertyName : StringLiteral 的评估如下:

  1. 返回 StringLiteral 的 SV [String value]。

生产 PropertyName : NumericLiteral 的评估如下:

  1. 让 nbr 是形成 NumericLiteral 值的结果。
  2. 返回到字符串(nbr)。

这意味着:

  • { theTop : 10 } 完全一样 { 'theTop' : 10 }

    PropertyName theTop是一个IdentifierName,所以它被转换为'theTop'字符串值,这是的字符串值'theTop'

  • 不可能用可变键编写对象初始值设定项(文字)。

    仅有的三个选项是IdentifierName(扩展为字符串文字)StringLiteral、 和NumericLiteral(也扩展为字符串)。

Downvoters:我是第一个在这个问题上引用任何标准的人。我回答编辑了顶部答案中的 ES6 引用,当时该标准尚未被接受。如果您碰巧知道为什么我会得到反对票,请解释一下,我只是想学习。我还不如得到同辈压力徽章...
2021-02-11 22:57:22
@Bergi 再次感谢向我解释!我已经更新它以使其更加明确。我之前没有这样做,因为我虽然很明显,因为我们可以写{a:1}.a,所以a很明显不会在标识符情况下扩展变量值。但是,是的,在这种情况下,进一步解释是一种改进。
2021-02-26 22:57:22
我想投票否决主要是因为您的回答没有提供解决方案,并且在这方面“没有用”。投票给同龄人压力:-)
2021-02-28 22:57:22
@Bergi 感谢您的勇气!:-) 但我想我已经直接回答了这个问题: 问:“为什么下面的方法有效?”。A:因为 ES5 是这么说的。“怎么办?” 是隐含的。在有人在 ES6 解决方案中编辑之前,您是否在没有标准引用的情况下对说“这是不可能的”的最高问题投了反对票?
2021-03-01 22:57:22
啊,对。当我直接回答它们时,我通常会在引用中引用特定问题以使其清楚。引用标准可以使答案更好,但目前您的帖子甚至没有回答 imo 问题。说明什么可以在 ES5 中生成密钥并不意味着它们是如何工作的。肯定thetop是一个IdentifierName,那么为什么它不起作用呢?这个问题仍然悬而未决。
2021-03-06 22:57:22

ES6 / 2020

如果您尝试使用来自任何其他来源的“key:value”将数据推送到对象,您可以使用以下内容:

let obj = {}
let key = "foo"
let value = "bar"

obj[`${key}`] = value

// A `console.log(obj)` would return:
// {foo: "bar}

// A `typeof obj` would return:
// "object"

希望这对某人有所帮助:)

我使用以下内容将具有“动态”名称的属性添加到对象:

var key = 'top';
$('#myElement').animate(
   (function(o) { o[key]=10; return o;})({left: 20, width: 100}),
   10
);

key 是新属性的名称。

传递给的属性对象animate将是{left: 20, width: 100, top: 10}

这只是使用[]其他答案推荐的所需符号,但代码行更少!