Is it possible to add dynamically named properties to JavaScript object?

后端 未结 19 1480
攒了一身酷
攒了一身酷 2020-11-21 05:39

In JavaScript, I\'ve created an object like so:

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

Is it poss

相关标签:
19条回答
  • 2020-11-21 06:22

    I know there are several answers to this post already, but I haven't seen one wherein there are multiple properties and they are within an array. And this solution by the way is for ES6.

    For illustration, let's say we have an array named person with objects inside:

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

    So, you can add a property with corresponding value. Let's say we want to add a Language with a default value of EN.

    Person.map((obj)=>({...obj,['Language']:"EN"}))
    

    The Person array now would become like this:

    Person = [{id:1, Name: "John", Language:"EN"}, 
    {id:2, Name: "Susan", Language:"EN"}, {id:3, Name: "Jet", Language:"EN"}]
    
    0 讨论(0)
  • 2020-11-21 06:22

    A perfect easy way

    var data = {
        'PropertyA': 1,
        'PropertyB': 2,
        'PropertyC': 3
    };
    
    var newProperty = 'getThisFromUser';
    data[newProperty] = 4;
    
    console.log(data);
    

    If you want to apply it on an array of data (ES6/TS version)

    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);
    
    0 讨论(0)
  • 2020-11-21 06:25

    I know that the question is answered perfectly, but I also found another way to add new properties and wanted to share it with you:

    You can use the function Object.defineProperty()

    Found on Mozilla Developer Network

    Example:

    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
    
    0 讨论(0)
  • 2020-11-21 06:29

    I was looking for a solution where I can use dynamic key-names inside the object declaration (without using ES6 features like ... or [key]: value)

    Here's what I came up with:

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

    It looks a little bit complex at first, but it's really simple. We use the Comma Operator to run three commands in a row:

    1. obj = {}: creates a new object and assigns it to the variable obj
    2. obj[field] = 123: adds a computed property name to obj
    3. obj: use the obj variable as the result of the parentheses/comma list

    This syntax can be used inside a function parameter without the requirement to explictely declare the obj variable:

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

    Some variations

    "strict mode" workaround:

    The above code does not work in strict mode because the variable "obj" is not declared.

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

    ES2015 code using computed property names in initializer:

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

    This solution works in all modern browsers (but not in IE, if I need to mention that)

    Super hacky way using 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}') );
    

    Allows special characters in keys

    Note that you can also use spaces and other special characters inside computed property names (and also in JSON.parse).

    var field = 'my dynamic field :)';
    showObject( {[field] = 123} );
    // result: { "my dynamic field :)": 123 }
    

    Those fields cannot be accessed using a dot (obj.my dynamic field :) is obviously syntactically invalid), but only via the bracket-notation, i.e., obj['my dynamic field :)'] returns 123

    0 讨论(0)
  • 2020-11-21 06:30

    Here's how I solved the problem.

    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 ) );
    

    Generates the following object:

    {
      "someouter": {
        "someinner": {
          "someValue": 123
        }
      },
      "simpleString": "string"
    }
    
    0 讨论(0)
  • 2020-11-21 06:33

    Yes.

    var data = {
        'PropertyA': 1,
        'PropertyB': 2,
        'PropertyC': 3
    };
    
    data["PropertyD"] = 4;
    
    // dialog box with 4 in it
    alert(data.PropertyD);
    alert(data["PropertyD"]);

    0 讨论(0)
提交回复
热议问题