在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?

当前回答

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

这是我想到的:

var obj = (obj = {}, obj[field] = 123, obj)

一开始看起来有点复杂,但其实很简单。我们使用逗号操作符在一行中运行三个命令:

Obj ={}:创建一个新对象并将其赋值给变量Obj Obj [field] = 123:向Obj添加计算属性名 Obj:使用Obj变量作为括号/逗号列表的结果

这种语法可以在函数形参中使用,而不需要显式声明obj变量:

//查看结果的test函数。 函数showObject(obj) { console.log (obj); } //动态字段名。 var field = "myDynamicField"; //调用动态对象的函数。 showObject((obj = {}, obj[field] = 123, obj)); / * 输出: { “myDynamicField”:真的 } * /

一些变化

“严格模式”解决方案:

上面的代码不能在严格模式下工作,因为没有声明变量“obj”。

// This gives the same result, but declares the global variable `this.obj`!
showObject( (this.obj = {}, obj[field] = 123, obj) );

在初始化器中使用计算属性名的ES2015代码:

// Works in most browsers, same result as the other functions.
showObject( {[field] = 123} );

这个解决方案适用于所有现代浏览器(但不适用于IE,如果我需要提及的话)

使用JSON.parse()的超级hack方式:

// 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

其他回答

从包含对象的动态字符串名(例如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相同

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
}

这使用了新的计算属性语法和模板字面量。

使用.(点)方法向现有对象添加属性时要小心。

(.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 }

注意控制台日志末尾的问题- 'key: 1999'而不是Property6: 6, Property7: 7,........., Property1999: 1999。因此,添加动态创建的属性的最佳方法是[括号]方法。

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

在你的例子中:

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

你可以用下面两种方式定义一个带有动态值的属性:

data.key = value;

or

data['key'] = value;

甚至,如果你的键也是动态的,你可以使用Object类定义:

Object.defineProperty(data, key, withValue(value));

其中data是对象,key是存储键名的变量,value是存储值的变量。

我希望这能有所帮助!

只是对上面的答案的补充。您可以定义一个函数来封装下面提到的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