是否可以向 JavaScript 对象添加动态命名的属性?

IT技术 javascript
2021-01-22 21:30:01

在 JavaScript 中,我创建了一个像这样的对象:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};

如果直到运行时才确定属性名称,是否可以在初始创建后向该对象添加更多属性?IE

var propName = 'Property' + someUserInput
//imagine someUserInput was 'Z', how can I now add a 'PropertyZ' property to 
//my object?
6个回答

是的。

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};

data["PropertyD"] = 4;

// dialog box with 4 in it
alert(data.PropertyD);
alert(data["PropertyD"]);

是我一个人还是这篇文章在获得 195 个赞成票时没有回答问题?我以为这是在询问如何定义名称未知的属性,直到它在 JavaScript 代码中生成。
2021-03-11 21:30:01
@thedz:data.PropertyD 需要知道属性名称,这不够动态。
2021-03-17 21:30:01
@Qantas:假设它没有直接回答。但是从data["PropertyD"]data[function_to_get_property_name()]似乎微不足道。
2021-03-26 21:30:01
+1 因为这对我有帮助。但我不明白为什么对象属性像数组一样处理。
2021-04-05 21:30:01
@Bondye:这是 javascript 奇怪设计的一部分。在这种情况下object["property"]与 不完全相同array[4],前者不是作为真正的数组创建的。
2021-04-06 21:30:01

ES6 取胜!

const b = 'b';
const c = 'c';

const data = {
    a: true,
    [b]: true, // dynamic property
    [`interpolated-${c}`]: true, // dynamic property + interpolation
    [`${b}-${c}`]: true
}

如果你登录,data你会得到这个:

{
  a: true,
  b: true,
  interpolated-c: true,
  b-c: true
}

这利用了新的Computed Property语法和Template Literals

在我希望我的代码完全正常运行的情况下,这就是我所需要的(例如,没有命令式语句说obj[propname])。相反,我能够将它与对象传播语法一起使用。
2021-03-12 21:30:01
@JackGiffin 在某些情况下是的,但是在使用不可变结构时,这种语法可能非常方便,因为您展示的方法是 mutating a(特别是在使用像 redux 这样的包时)
2021-03-13 21:30:01
这是真正有助于动态构建它的正确答案,谢谢!
2021-03-25 21:30:01
这太棒了 { ...state, [prop]: val }
2021-03-27 21:30:01
对于没有看过或理解新语法的人来说,这段代码片段正在做什么并不是很明显。我建议进行编辑以使用“a”常量显示输出/预期属性。
2021-04-01 21:30:01

对的,这是可能的。假设:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};
var propertyName = "someProperty";
var propertyValue = "someValue";

任何一个:

data[propertyName] = propertyValue;

或者

eval("data." + propertyName + " = '" + propertyValue + "'");

优选第一种方法。如果您使用用户提供的值,则 eval() 具有明显的安全问题,因此如果您可以避免使用它,请不要使用它,但值得知道它的存在以及它可以做什么。

你可以参考这个:

alert(data.someProperty);

或者

data(data["someProperty"]);

或者

alert(data[propertyName]);
注意(以防有人遇到和我一样的问题):对于普通对象,这可以正常工作。但是我必须向 jQuery UI 对象添加一些属性以跟踪项目列表。在这种情况下,如果以这种方式添加该属性就会丢失,因为 jQuery 总是会创建一个副本。在这里你需要使用jQuery.extend()
2021-03-09 21:30:01
使用 eval 真的很危险。
2021-03-19 21:30:01
@GeorgSchölly 是的。
2021-03-23 21:30:01
我想添加到我之前的评论中 - 即使在我的情况下也不起作用。所以我最终使用了$("#mySelector").data("propertyname", myvalue);来设置和var myValue=$("#mySelector").data("propertyname");取回值。甚至可以通过这种方式添加复杂的对象(列表、数组...)。
2021-04-07 21:30:01

我知道这个问题得到了完美的回答,但我也找到了另一种添加新属性的方法,并想与您分享:

您可以使用该功能 Object.defineProperty()

Mozilla 开发者网络上找到

例子:

var o = {}; // Creates a new object

// Example of an object property added with defineProperty with a data property descriptor
Object.defineProperty(o, "a", {value : 37,
                               writable : true,
                               enumerable : true,
                               configurable : true});
// 'a' property exists in the o object and its value is 37

// Example of an object property added with defineProperty with an accessor property descriptor
var bValue;
Object.defineProperty(o, "b", {get : function(){ return bValue; },
                               set : function(newValue){ bValue = newValue; },
                               enumerable : true,
                               configurable : true});
o.b = 38;
// 'b' property exists in the o object and its value is 38
// The value of o.b is now always identical to bValue, unless o.b is redefined

// You cannot try to mix both :
Object.defineProperty(o, "conflict", { value: 0x9f91102, 
                                       get: function() { return 0xdeadbeef; } });
// throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors
@Trevor:完全可配置性和添加 getter 和 setter 的能力;此外,能够使用defineProperties(复数)一次添加多个属性
2021-03-24 21:30:01
@ThieliciousObject.defineProperty并不意味着成为简单方便的工具,而是具有细粒度控制的工具。如果您不需要额外的控制,那么它不是正确的选择工具。
2021-03-29 21:30:01
这种方法的优缺点?
2021-04-01 21:30:01
Object.defineProperty(obj, prop, valueDescriptor)V8 的优化比简单地执行要慢得多,也更难obj[prop] = value
2021-04-02 21:30:01
这是最好的解决方案。obj[prop] = value当您尝试使用以下函数解析对象时,动态创建条目 with会让您头疼Object.getOwnPropertyNames
2021-04-03 21:30:01

ES6 引入了计算属性名称,它允许你做

let a = 'key'
let myObj = {[a]: 10};
// output will be {key:10}