在JavaScript中,我创建了一个像这样的对象:
var data = {
'PropertyA': 1,
'PropertyB': 2,
'PropertyC': 3
};
如果在运行时之前未确定属性名称,是否可以在初始创建后为此对象添加更多属性?即。
var propName = 'Property' + someUserInput
//imagine someUserInput was 'Z', how can I now add a 'PropertyZ' property to
//my object?
答案 0 :(得分:1067)
是
var data = {
'PropertyA': 1,
'PropertyB': 2,
'PropertyC': 3
};
data["PropertyD"] = 4;
// dialog box with 4 in it
alert(data.PropertyD);
alert(data["PropertyD"]);
答案 1 :(得分:104)
获胜的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。
答案 2 :(得分:81)
是的,这是可能的。假设:
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]);
答案 3 :(得分:53)
我知道这个问题得到了很好的回答,但我也找到了另一种方法来添加新属性,并希望与您分享:
您可以使用Object.defineProperty()
示例:
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
答案 4 :(得分:20)
在这里,使用您的符号:
var data = {
'PropertyA': 1,
'PropertyB': 2,
'PropertyC': 3
};
var propName = 'Property' + someUserInput
//imagine someUserInput was 'Z', how can I now add a 'PropertyZ' property to
//my object?
data[propName] = 'Some New Property value'
答案 5 :(得分:17)
除了之前的所有答案,如果您想知道我们将如何使用计算属性名称(ECMAScript 6)在 Future 中编写动态属性名称,请按以下步骤操作:
var person = "John Doe";
var personId = "person_" + new Date().getTime();
var personIndex = {
[ personId ]: person
// ^ computed property name
};
personIndex[ personId ]; // "John Doe"
答案 6 :(得分:16)
您只需使用点符号即可添加更多属性:
var data = {
var1:'somevalue'
}
data.newAttribute = 'newvalue'
或强>:
data[newattribute] = somevalue
用于动态键。
答案 7 :(得分:11)
只是上述abeing答案的补充。您可以定义一个函数来封装defineProperty的复杂性,如下所述。
var defineProp = function ( obj, key, value ){
var config = {
value: value,
writable: true,
enumerable: true,
configurable: true
};
Object.defineProperty( obj, key, config );
};
//Call the method to add properties to any object
defineProp( data, "PropertyA", 1 );
defineProp( data, "PropertyB", 2 );
defineProp( data, "PropertyC", 3 );
参考:http://addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript
答案 8 :(得分:7)
您可以使用以下某些选项动态添加属性:
在你的例子中:
var data = {
'PropertyA': 1,
'PropertyB': 2,
'PropertyC': 3
};
您可以在接下来的两种方式中定义具有动态值的属性:
data.key = value;
或
data['key'] = value;
更多..如果您的密钥也是动态的,您可以使用Object类定义:
Object.defineProperty(data, key, withValue(value));
数据 是您的对象, 密钥 是存储密钥名称的变量, value 是存储值的变量。
我希望这有帮助!
答案 9 :(得分:5)
我知道这个帖子已有几个答案,但我还没有看到一个有多个属性并且它们在一个数组中的答案。顺便提一下,这个解决方案适用于ES6。
为了说明,我们假设我们有一个名为person的数组,其中包含对象:
=DCount("*", "Query1")
=DCount("*", "Query2")
=DCount("*", "Query3")
因此,您可以添加具有相应值的属性。我们假设我们要添加语言,默认值为 EN 。
let Person = [{id:1, Name: "John"}, {id:2, Name: "Susan"}, {id:3, Name: "Jet"}]
Person 数组现在会变成这样:
Person.map((obj)=>({...obj,['Language']:"EN"}))
答案 10 :(得分:4)
最简单,最便携的方式是。
var varFieldName = "good";
var ob = {};
Object.defineProperty(ob, varFieldName , { value: "Fresh Value" });
基于#abeing的答案!
答案 11 :(得分:1)
从包含对象的动态字符串名称访问的好方法(例如object.subobject.property)
function ReadValue(varname)
{
var v=varname.split(".");
var o=window;
if(!v.length)
return undefined;
for(var i=0;i<v.length-1;i++)
o=o[v[i]];
return o[v[v.length-1]];
}
function AssignValue(varname,value)
{
var v=varname.split(".");
var o=window;
if(!v.length)
return;
for(var i=0;i<v.length-1;i++)
o=o[v[i]];
o[v[v.length-1]]=value;
}
示例:
ReadValue("object.subobject.property");
WriteValue("object.subobject.property",5);
eval适用于读取值,但写入值有点困难。
更高级的版本(如果它们不存在则创建子类,并允许对象而不是全局变量)
function ReadValue(varname,o=window)
{
if(typeof(varname)==="undefined" || typeof(o)==="undefined" || o===null)
return undefined;
var v=varname.split(".");
if(!v.length)
return undefined;
for(var i=0;i<v.length-1;i++)
{
if(o[v[i]]===null || typeof(o[v[i]])==="undefined")
o[v[i]]={};
o=o[v[i]];
}
if(typeof(o[v[v.length-1]])==="undefined")
return undefined;
else
return o[v[v.length-1]];
}
function AssignValue(varname,value,o=window)
{
if(typeof(varname)==="undefined" || typeof(o)==="undefined" || o===null)
return;
var v=varname.split(".");
if(!v.length)
return;
for(var i=0;i<v.length-1;i++)
{
if(o[v[i]]===null || typeof(o[v[i]])==="undefined")
o[v[i]]={};
o=o[v[i]];
}
o[v[v.length-1]]=value;
}
示例:
ReadValue("object.subobject.property",o);
WriteValue("object.subobject.property",5,o);
这与o.object.subobject.property
相同答案 12 :(得分:1)
要小心,请使用。(点)方法向现有对象添加属性。
(。dot)向对象添加属性的方法仅在您知道 “键” 时使用,否则请使用 [括号] 方法。
示例:
var data = {
'Property1': 1
};
// Two methods of adding a new property [ key (Property4), value (4) ] to the
// existing object (data)
data['Property2'] = 2; // bracket method
data.Property3 = 3; // dot method
console.log(data); // { Property1: 1, Property2: 2, Property3: 3 }
// But if 'key' of a property is unknown and will be found / calculated
// dynamically then use only [bracket] method not a dot method
var key;
for(var i = 4; i < 6; ++i) {
key = 'Property' + i; // Key - dynamically calculated
data[key] = i; // CORRECT !!!!
}
console.log(data);
// { Property1: 1, Property2: 2, Property3: 3, Property4: 4, Property5: 5 }
for(var i = 6; i < 2000; ++i) {
key = 'Property' + i; // Key - dynamically calculated
data.key = i; // WRONG !!!!!
}
console.log(data);
// { Property1: 1, Property2: 2, Property3: 3,
// Property4: 4, Property5: 5, key: 1999 }
请注意控制台日志末尾的问题- “键:1999” ,而不是属性6:6,属性7:7,.........,属性1999:1999 。因此,添加动态创建的属性的最佳方法是[bracket]方法。
答案 13 :(得分:1)
ES6引入了计算所得的属性名称,您可以这样做
let a = 'key'
let myObj = {[a]: 10};
// output will be {key:10}
答案 14 :(得分:1)
我一直在寻找一种解决方案,可以在对象声明中使用动态键名(不使用...
或[key]: value
之类的ES6功能)
这是我想出的:
var obj = (obj = {}, obj[field] = 123, obj)
乍一看似乎有点复杂,但这确实很简单。我们使用逗号运算符连续运行三个命令:
obj = {}
:创建一个新对象并将其分配给变量obj
obj[field] = 123
:将computed property name添加到obj
obj
:使用obj
变量作为括号/逗号列表的结果此语法可在函数参数内使用,而无需明确声明obj
变量:
// The test function to see the result.
function showObject(obj) {
console.log(obj);
}
// My dynamic field name.
var field = "myDynamicField";
// Call the function with our dynamic object.
showObject( (obj = {}, obj[field] = 123, obj) );
/*
Output:
{
"myDynamicField": true
}
*/
上面的代码在strict mode
中不起作用,因为未声明变量“ obj”。
// This gives the same result, but declares the global variable `this.obj`!
showObject( (this.obj = {}, obj[field] = 123, obj) );
在初始化器中使用计算出的属性名称的// Works in most browsers, same result as the other functions.
showObject( {[field] = 123} );
此解决方案可在all modern browsers中使用(但如果需要说明,则不能在IE中使用)
JSON.parse()
的超级黑客方式:// Create a JSON string that is parsed instantly. Not recommended in most cases.
showObject( JSON.parse( '{"' + field +'":123}') );
// read: showObject( JSON.parse( '{"myDynamicfield":123}') );
请注意,您还可以在计算出的属性名称(以及JSON.parse)中使用空格和其他特殊字符。
var field = 'my dynamic field :)';
showObject( {[field] = 123} );
// result: { "my dynamic field :)": 123 }
这些字段不能使用点来访问(obj.my dynamic field :)
在语法上显然无效),而只能通过括号表示,即obj['my dynamic field :)']
返回123
答案 15 :(得分:0)
以下是我解决问题的方法。
var obj = {
};
var field = "someouter.someinner.someValue";
var value = 123;
function _addField( obj, field, value )
{
// split the field into tokens
var tokens = field.split( '.' );
// if there's more than one token, this field is an object
if( tokens.length > 1 )
{
var subObj = tokens[0];
// define the object
if( obj[ subObj ] !== undefined ) obj[ subObj ] = {};
// call addfield again on the embedded object
var firstDot = field.indexOf( '.' );
_addField( obj[ subObj ], field.substr( firstDot + 1 ), value );
}
else
{
// no embedded objects, just field assignment
obj[ field ] = value;
}
}
_addField( obj, field, value );
_addField(obj, 'simpleString', 'string');
console.log( JSON.stringify( obj, null, 2 ) );
生成以下对象:
{
"someouter": {
"someinner": {
"someValue": 123
}
},
"simpleString": "string"
}
答案 16 :(得分:0)
一种完美的简便方法
var data = {
'PropertyA': 1,
'PropertyB': 2,
'PropertyC': 3
};
var newProperty = 'getThisFromUser';
data[newProperty] = 4;
console.log(data);
如果要将其应用于数据数组(ES6 / TS版)
const data = [
{ 'PropertyA': 1, 'PropertyB': 2, 'PropertyC': 3 },
{ 'PropertyA': 11, 'PropertyB': 22, 'PropertyC': 33 }
];
const newProperty = 'getThisFromUser';
data.map( (d) => d[newProperty] = 4 );
console.log(data);
答案 17 :(得分:0)
如果在运行时添加了新属性,则可能会很有用:
data = { ...data, newPropery: value}
但是,散布运算符使用浅表复制,但此处我们将数据分配给自身,因此应该不会丢失任何数据
答案 18 :(得分:0)
是的,有可能。我已经实现了使用下面的实现。为此,我得到一个响应数组,我想要一个对象作为属性列表。
response = {
"equityMonths": [
{
"id": 1,
"month": "JANUARY",
"isEligible": false
},
{
"id": 2,
"month": "FEBRUARY",
"isEligible": true
},
{
"id": 3,
"month": "MARCH",
"isEligible": false
},
{
"id": 4,
"month": "APRIL",
"isEligible": true
},
{
"id": 5,
"month": "MAY",
"isEligible": false
},
{
"id": 6,
"month": "JUNE",
"isEligible": true
},
{
"id": 7,
"month": "JULY",
"isEligible": true
},
{
"id": 8,
"month": "AUGUST",
"isEligible": false
},
{
"id": 9,
"month": "SEPTEMBER",
"isEligible": true
},
{
"id": 10,
"month": "OCTOBER",
"isEligible": false
},
{
"id": 11,
"month": "NOVEMBER",
"isEligible": true
},
{
"id": 12,
"month": "DECEMBER",
"isEligible": false
}
]
}
在这里,我希望将equityMonths
作为对象,并将Jan到Dec用作键,并将isEligible
作为值。为此,我们必须使用Object类的defineProperty()
方法,该方法允许将动态属性添加到对象中。
用于向对象动态添加属性的代码。
let equityMonth = new Object();
response.equityMonths.forEach(element => {
Object.defineProperty(equityMonth, element['month'], {
value: element['isEligible'],
writable: true,
enumerable: true,
configurable: true
});
});
console.log("DATA : " + JSON.stringify(equityMonth));
在上面的代码中,我们有equityMonths
数组,我们将其转换为对象的属性。
输出:
DATA : {"JANUARY":false,"FEBRUARY":true,"MARCH":false,"APRIL":true,"MAY":false,"JUNE":true,"JULY":true,"AUGUST":false,"SEPTEMBER":true,"OCTOBER":false,"NOVEMBER":true,"DECEMBER":false}
答案 19 :(得分:-10)
当然。可以将其视为字典或关联数组。你可以随时添加它。