Is het mogelijk om dynamisch genoemde eigenschappen aan JavaScript-object toe te voegen?

In JavaScript heb ik een object opgericht zoals SO:

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

Is het mogelijk om verdere eigenschappen aan dit object toe te voegen na de initiële creatie als de naam van de eigenschappen niet wordt bepaald totdat de tijdstip is? d.w.z.

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

1, Autoriteit 100%

Ja.

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

2, Autoriteit 14%

ES6 voor de overwinning!

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

Als u logt datakrijgt u dit:

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

Dit maakt gebruik van de nieuwe Berekende eigenschap syntaxis en Sjabloonletters.


Antwoord 3, autoriteit 6%

Ja, dat is mogelijk. Ervan uitgaande:

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

Ofwel:

data[propertyName] = propertyValue;

of

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

De eerste methode heeft de voorkeur. eval() heeft de voor de hand liggende beveiligingsproblemen als je waarden gebruikt die door de gebruiker zijn opgegeven, dus gebruik het niet als je het kunt vermijden, maar het is de moeite waard om te weten dat het bestaat en wat het kan doen.

Je kunt hiernaar verwijzen met:

alert(data.someProperty);

of

data(data["someProperty"]);

of

alert(data[propertyName]);

Antwoord 4, autoriteit 5%

Ik weet dat de vraag perfect is beantwoord, maar ik heb ook een andere manier gevonden om nieuwe eigendommen toe te voegen en wilde deze met u delen:

U kunt de functie Object.defineProperty()

gebruiken

gevonden op Mozilla-ontwikkelaarsnetwerk

Voorbeeld:

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

5, Autoriteit 4%

ES6 introduceert berekende eigendomsnamen, waarmee u

kunt doen

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

6, Autoriteit 2%

Hier, met behulp van uw notatie:

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'

Antwoord 7

Je kunt zoveel meer eigenschappen toevoegen als je wilt door simpelweg de puntnotatie te gebruiken:

var data = {
    var1:'somevalue'
}
data.newAttribute = 'newvalue'

of:

data[newattribute] = somevalue

voor dynamische toetsen.


Antwoord 8

naast alle voorgaande antwoorden, en voor het geval u zich afvraagt hoe we dynamische eigenschapsnamen in de Toekomstgaan schrijven met behulp van berekende eigenschapsnamen ( ECMAScript 6 ), gaat u als volgt te werk:

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

referentie: ECMAScript 6 begrijpen – Nickolas Zakas


Antwoord 9

Gewoon een aanvulling op het antwoord van abeing hierboven. U kunt een functie definiëren om de complexiteit van defineProperty in te kapselen, zoals hieronder vermeld.

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

referentie: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#constructorpatternjavascript


Antwoord 10

U kunt eigenschappen dynamisch toevoegen met behulp van enkele van de onderstaande opties:

In jou voorbeeld:

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

U kunt een eigenschap met een dynamische waarde op de volgende twee manieren definiëren:

data.key = value;

of

data['key'] = value;

Zeker nog..als uw sleutel ook dynamisch is, kunt u de klasse Object definiëren met:

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

waar datauw object is, is keyde variabele om de sleutelnaam op te slaan en waardeis de variabele om de waarde op te slaan.

Ik hoop dat dit helpt!


Antwoord 11

Ik weet dat er al verschillende antwoorden op dit bericht zijn, maar ik heb er nog geen gezien waarin er meerdere eigenschappen zijn en deze zich in een array bevinden. En deze oplossing is trouwens voor ES6.

Laten we ter illustratie zeggen dat we een array hebben met de naam person met objecten erin:

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

Je kunt dus een eigenschap met bijbehorende waarde toevoegen. Stel dat we een Taalwillen toevoegen met de standaardwaarde EN.

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

De Persoonarray zou nu als volgt worden:

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

Antwoord 12

Ik was op zoek naar een oplossing waarbij ik dynamische sleutelnamen binnen de objectdeclaratie kan gebruiken (zonder ES6-functies zoals ...of [key]: valuete gebruiken )

Dit is wat ik heb bedacht:

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

Het ziet er in het begin een beetje ingewikkeld uit, maar het is heel eenvoudig. We gebruiken de komma-operator om drie opdrachten achter elkaar uit te voeren:

  1. obj = {}: maakt een nieuw object en wijst het toe aan de variabele obj
  2. obj[field] = 123: voegt een berekende eigenschapsnaamnaar obj
  3. obj: gebruik de variabele objals resultaat van de lijst met haakjes/komma’s

Deze syntaxis kan binnen een functieparameter worden gebruikt zonder dat de variabele objexpliciet hoeft te worden gedeclareerd:

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

Antwoord 13

De eenvoudigste en meest draagbare manier is.

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

Gebaseerd op #abeing antwoord!


Antwoord 14

Het kan handig zijn als een gemengde nieuwe eigenschap in runtime wordt toegevoegd:

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

De spread-operator gebruikt echter een ondiepe kopie, maar hier wijzen we gegevens aan zichzelf toe, zodat er niets verloren gaat


Antwoord 15

Wees voorzichtigbij het toevoegen van een eigenschap aan het bestaande object met behulp van de .(dot)-methode.

(.dot)methode voor het toevoegen van een eigenschap aan het object mag alleen worden gebruikt als u kentde ‘sleutel’vooraf gebruik anders de [bracket]methode.

Voorbeeld:

  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 }

16

Een leuke manier om toegang te krijgen van dynamische stringnamen die objecten bevatten (bijvoorbeeld 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;
}

Voorbeeld:

ReadValue("object.subobject.property");
WriteValue("object.subobject.property",5);

EVAL WERKEN VOOR LEAD-waarde, maar de schrijfwaarde is een beetje moeilijker.

Een meer geavanceerde versie (maak subclasses als ze niet bestaan, en objecten in plaats van globale variabelen toestaan)

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

Voorbeeld:

ReadValue("object.subobject.property",o);
WriteValue("object.subobject.property",5,o);

Dit is hetzelfde als o.object.subobject.property


Antwoord 17

Zo heb ik het probleem opgelost.

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

Genereert het volgende object:

{
  "someouter": {
    "someinner": {
      "someValue": 123
    }
  },
  "simpleString": "string"
}

18

Een perfecte eenvoudige manier

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

Als u deze wilt toepassen op een reeks gegevens (ES6 / TS-versie)

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

Antwoord 19

Absoluut. Zie het als een woordenboek of associatieve array. Je kunt er op elk moment iets aan toevoegen.

Other episodes