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

是否可以向JavaScript对象添加动态命名的属性?,javascript,Javascript,在JavaScript中,我创建了如下对象: var data = { 'PropertyA': 1, 'PropertyB': 2, 'PropertyC': 3 }; 如果直到运行时才确定属性名称,是否可以在初始创建后向该对象添加更多属性?i、 e var propName = 'Property' + someUserInput //imagine someUserInput was 'Z', how can I now add a 'PropertyZ' pro

在JavaScript中,我创建了如下对象:

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

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

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

var数据={
"物业a":1,,
“PropertyB”:2,
“PropertyC”:3
};
数据[“PropertyD”]=4;
//对话框,其中有4个
警报(data.PropertyD);

警报(数据[“PropertyD”])是,这是可能的。假设:

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

data[propertyName] = propertyValue;

首选第一种方法。如果使用用户提供的值,eval()会有明显的安全问题,因此如果可以避免,请不要使用eval(),但知道eval()的存在及其功能是值得的

您可以通过以下方式进行参考:

alert(data.someProperty);


只需使用点符号,即可添加任意多个属性:

var data = {
    var1:'somevalue'
}
data.newAttribute = 'newvalue'
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'

data[newattribute] = somevalue

对于动态键。

绝对正确。可以将其视为字典或关联数组。您可以随时添加到它。

此处,使用您的符号:

var data = {
    var1:'somevalue'
}
data.newAttribute = 'newvalue'
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'

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

您可以使用函数
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
ReadValue("object.subobject.property");
WriteValue("object.subobject.property",5);
ReadValue("object.subobject.property",o);
WriteValue("object.subobject.property",5,o);

除了前面的所有答案之外,如果您想知道将来如何使用计算属性名(ECMAScript 6)编写动态属性名,请看以下方法:

var person = "John Doe";
var personId = "person_" + new Date().getTime();
var personIndex = {
    [ personId ]: person
//  ^ computed property name
};

personIndex[ personId ]; // "John Doe"


参考资料:

只是对阿宾上述答案的补充。您可以定义一个函数来封装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 );

参考:

您可以使用以下一些选项动态添加属性:

在你的例子中:

var data = {
    'PropertyA': 1,
    'PropertyB': 2,
    'PropertyC': 3
};
可以通过以下两种方式定义具有动态值的特性:

data.key = value;

甚至更多..如果您的键也是动态的,则可以使用对象类定义:

Object.defineProperty(data, key, withValue(value));
其中,数据是对象,是存储键名的变量,是存储值的变量

我希望这有帮助

ES6为胜利而战

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

const data = {
    a: true,
    [b]: true, // dynamic property
    [`interpolated-${c}`]: true, // dynamic property + interpolation
    [`${b}-${c}`]: true
}
如果您记录
数据
,您会得到以下信息:

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

这利用了新的语法和语法。最简单、最可移植的方法是

var varFieldName = "good";
var ob = {};
Object.defineProperty(ob, varFieldName , { value: "Fresh Value" });

基于#教唆回答

下面是我如何解决这个问题的

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"
}

从包含对象(例如object.subobject.property)的动态字符串名称进行访问的好方法

eval适用于读取值,但写入值更难

更高级的版本(如果不存在子类,则创建子类,并允许对象而不是全局变量)


这与o.object.subobject.property是一样的,我知道这篇文章已经有几个答案了,但我还没有看到一个答案,其中有多个属性,并且它们位于一个数组中。顺便说一下,这个解决方案是针对ES6的

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;
}
为了便于说明,假设我们有一个名为person的数组,其中包含对象:

 let Person = [{id:1, Name: "John"}, {id:2, Name: "Susan"}, {id:3, Name: "Jet"}]
因此,可以添加具有相应值的属性。假设我们想添加一种默认值为EN语言

Person.map((obj)=>({...obj,['Language']:"EN"}))
Person数组现在会变成这样:

Person = [{id:1, Name: "John", Language:"EN"}, 
{id:2, Name: "Susan", Language:"EN"}, {id:3, Name: "Jet", Language:"EN"}]

使用(点)方法向现有对象添加属性时,请小心

(.dot)只有在事先知道键的情况下才能使用向对象添加属性的方法,否则使用[括号]方法

示例:

var数据={
“属性1”:1
};
//将新属性[键(Property4),值(4)]添加到
//现有对象(数据)
数据['Property2']=2;//交叉法
data.Property3=3;//点法
console.log(数据);//{属性1:1,属性2:2,属性3:3}
//但如果某个属性的“键”未知且将被找到/计算
//然后动态地只使用[括号]方法,而不是点方法
var键;
对于(变量i=4;i<6;++i){
key='Property'+i;//key-动态计算
data[key]=i;//正确!!!!
}
控制台日志(数据);
//{财产1:1,财产2:2,财产3:3,财产4:4,财产5:5}
对于(变量i=6;i<2000;++i){
key='Property'+i;//key-动态计算
data.key=i;//错误!!!!!
}
控制台日志(数据);
//{财产1:1,财产2:2,财产3:3,
//属性4:4,属性5:5,键:1999}
一个完美的简单方法

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

var newProperty = 'getThisFromUser';
data[newProperty] = 4;

console.log(data);
如果要将其应用于数据数组(ES6/TS版本)


ES6引入了计算属性名,允许您

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

如果在运行时混合了新属性外接程序,则它可能很有用:

data = { ...data, newPropery: value}

但是,spread运算符使用浅拷贝,但这里我们将数据分配给它本身,因此应该不会丢失任何内容

我正在寻找一种解决方案,在该解决方案中,我可以在对象声明中使用动态键名(而不使用ES6功能,如
..
[key]:value

以下是我的想法:

var obj = (obj = {}, obj[field] = 123, obj)
一开始看起来有点复杂,但实际上很简单。我们使用逗号运算符在一行中运行三个命令:

  • obj={}
    :创建一个新对象并将其分配给变量
    obj
  • obj[field]=123
    :向
    obj
  • obj
    :使用
    obj
    变量作为括号/逗号列表的结果
  • 此语法可在函数参数内使用,无需明确声明
    obj
    变量:

    //测试函数以查看结果。
    函数showObject(obj){
    控制台日志(obj);
    }
    //我的动态字段名。
    var field=“myDynamicField”;
    //使用我们的
    
    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);
    
    let a = 'key'
    let myObj = {[a]: 10};
    // output will be {key:10}
    
    data = { ...data, newPropery: value}
    
    var obj = (obj = {}, obj[field] = 123, obj)
    
    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
        }
      ]
    }
    
    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));
    
    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}