【问题标题】:Is it possible to define a dynamically named property using object literal in JavaScript? [duplicate]是否可以在 JavaScript 中使用对象文字定义动态命名的属性? [复制]
【发布时间】:2012-12-09 11:35:23
【问题描述】:

考虑以下

var a = {foo: "bar"};

相当于

var a = {};
a.foo = "bar";

相当于

var a = {};
a['foo'] = "bar";

相当于

var a = {}
var b = "foo";
a[b] = "bar";

是否可以做类似的事情

var b = "foo";
var a = { [b]: "bar" };

这样的结果是

// => {foo: "bar"}

可接受的解决方案是 JavaScript 或 CoffeeScript

【问题讨论】:

  • 我认为a[b] = "bar" 是唯一的方法。

标签: javascript coffeescript


【解决方案1】:

没有。

没有办法使用对象文字表示法来做到这一点。


更新:根据ECMAScript standard 6.0,您现在可以执行以下操作:

var b = 'foo';
var a = { [b]: 'bar' };

console.log( a.foo );  // "bar"

但是,此解决方案不适用于旧浏览器,do not support ES6

【讨论】:

  • 当然,还有一个更好的未提及的函数,它可以以每次运行时调用编译器为代价。
【解决方案2】:

截至 CoffeeScript version 1.9.1 这有效:

b = "foo"
a = "#{b}": "bar"

它编译为:

var a, b, obj;

b = "foo";

a = (
  obj = {},
  obj["" + b] = "bar",
  obj
);

Try it.

【讨论】:

    【解决方案3】:

    ES6 支持计算属性。

    // code from my original question now works in ES6 !
    let b = "foo";
    let a = { [b]: "bar" };
    
    a.foo; //=> "bar"
    

    [] 中可以使用任何表达式来定义属性名称

    let a = {
      [(xs => xs.join(''))(['f','o','o'])]: 'bar'
    };
    
    a.foo; //=> "bar"
    

    如果您需要在 ES5 世界中依赖此行为,您可以依靠功能强大的 babel.js 将您的 ES6 代码转换为 ES5 兼容代码。

    【讨论】:

      【解决方案4】:

      正如其他人所说,不,目前在 CoffeeScript 的对象文字中没有用于插入键字符串的语法;但似乎在某些时候这个功能存在!在这些 GitHub 问题中有一些关于它的讨论:#786#1731

      它在CocoLiveScript 中实现为:

      b = 'foo'
      a = {"#{b}": 'baz'}
      
      # Or..
      a = {(b): 'bar'}
      

      【讨论】:

        【解决方案5】:

        JSON 解析允许您将 JSON 字符串转换为对象:

        JSON.parse('{"'+dynamicProperty+'":"bar"}');
        

        这不完全是一个对象字面量,但如果您的目标是输入您的属性名称作为变量,它可以工作。

        【讨论】:

        • 我怎么忘了这件事。好想法。我想你想要:,而不是=,对吧?
        • 一个更准确的版本(考虑到属性名称中的双引号和其他特殊字符)是JSON.parse('{'+JSON.stringify(dynamicProperty)+':"bar"}'),但那时为什么不把它写成两行(ES6 之前)? (别介意我的时光机)
        【解决方案6】:

        要回答您的问题,这是我所知道的唯一方法。它使用eval。但请注意,eval 是邪恶的!

        var b = "foo";
        var a = eval('({ ' + b + ': ' + '"bar"' + ' })');
        

        这是一个丑陋的解决方案。为了安全起见,你不应该依赖这个。 不要使用它!

        【讨论】:

        • 为什么在这种情况下是邪恶的?我不明白为什么人们认为eval 100% 是邪恶的......
        • 既然人们不喜欢eval,还有另一种方式:new Function("return {" + b + ": 'bar'}")()
        • @Ian 因为eval 充分适用的情况非常少。 eval 在这种情况下甚至不是一个好的解决方案,它是一个 hack。
        • @David 这并不会使它变得邪恶。我可以理解一个论点,即它是“不必要的”。当人们说“邪恶”时,我敢打赌他们在想“危险”,因为这就是 SO 上的人们在看到它时立即声称的。我同意这不是一个“解决方案”,但是从什么时候开始黑客不是解决方案?在这种情况下,它不会以的性能为代价去做一堆额外的事情。如果JSON 不可用,这不是解析 JSON 的方式吗?您没有看到人们循环遍历 JSON 字符串的所有字符、解析它并以这种方式构建对象文字
        【解决方案7】:

        JavaScript

        var a, b;
        (a = {})[b = 'foo'] = 'bar';
        

        咖啡脚本

        (a = {})[b = 'foo'] = 'bar'
        

        【讨论】:

        • 抱歉,这不是对象字面量。
        • 这与OP提到的基本相同。
        • 我只是给你最简洁的写法。
        • @naomik 怎么样? a 是一个对象字面量,属性“foo”立即设置为“bar”。不幸的是,它在技术上已经是 OP 所拥有的,只是浓缩
        • @CaseyFoster,感谢您的帮助,但我需要它是一个对象文字。
        猜你喜欢
        • 2010-11-14
        • 2012-03-04
        • 2012-04-24
        • 1970-01-01
        • 2015-12-16
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多