Er det mulig å legge til dynamisk navngitte egenskaper til et JavaScript-objekt?


I JavaScript har jeg opprettet et objekt slik:

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

Er det mulig å legge til flere egenskaper til dette objektet etter dets opprinnelige opprettelse hvis egenskapenes navn ikke er bestemt før kjøretid? dvs.

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

Svar #1

Ja.

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

data["PropertyD"] = 4;

// dialog box with 4 in it
alert(data.PropertyD);
alert(data["PropertyD"]);

Svar #2

ES6 til seier!

const b = 'B';
const c = 'C';

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

Hvis du logger data, får du dette:

{
  a: true,
  B: true,
  interpolated-C: true,
  B-C: true
}

Dette gjør bruk av den nye syntaksen for beregnede egenskaper og mal-litteraler.

Svar #3

Ja, det er mulig. Forutsatt:

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

Enten :

data[propertyName] = propertyValue;

eller

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

Den første metoden foretrekkes. eval() har åpenbare sikkerhetsproblemer hvis du bruker verdier levert av brukeren, så ikke bruk det hvis du kan unngå det, men det er verdt å vite at det eksisterer og hva det kan gjøre.

Du kan referere til dette med:

alert(data.someProperty);

eller

data(data["someProperty"]);

eller

alert(data[propertyName]);

Svar #4

ES6 introduserer beregnede egenskapsnavn, som lar deg gjøre

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

Svar #5

Jeg vet at spørsmålet er besvart perfekt, men jeg fant også en annen måte å legge til nye egenskaper på og ville dele den med deg:

Du kan bruke funksjonen Object.defineProperty()

Funnet på Mozilla Developer Network

Eksempel :

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

Svar #6

Her, ved å bruke notasjonen din:

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'

Svar #7

Du kan legge til så mange flere egenskaper du vil, bare ved å bruke punktnotasjon:

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

eller:

data[newattribute] = somevalue

for dynamiske nøkler.

Svar #8

i tillegg til alle de tidligere svarene, og hvis du lurer på hvordan vi skal skrive dynamiske egenskapsnavn i Fremtiden ved hjelp av beregnede egenskapsnavn (ECMAScript 6), her er hvordan:

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

personIndex[ personId ]; // "John Doe"

referanse: Forstå ECMAScript 6 - Nickolas Zakas

Svar #9

Bare et tillegg til abeing sitt svar ovenfor. Du kan definere en funksjon for å kapsle inn kompleksiteten til defineProperty som nevnt nedenfor.

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

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

Svar #10

Du kan legge til egenskaper dynamisk ved å bruke noen av alternativene nedenfor:

I ditt eksempel:

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

Du kan definere en egenskap med en dynamisk verdi på de neste to måtene:

data.key = value;

eller

data['key'] = value;

Enda mer... hvis nøkkelen din også er dynamisk, kan du definere den ved å bruke Object-klassen med:

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

hvor data er objektet ditt, key er variabelen for å lagre nøkkelnavnet, og value er variabelen for å lagre verdien.

Jeg håper dette hjelper!

Svar #11

Det kan være nyttig hvis nye egenskaper legges til under kjøretid:

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

Men spread-operatoren bruker en grunn kopi, men her tilordner vi data til seg selv, så vi bør ikke miste noe

Svar #12

Jeg vet at det allerede finnes flere svar på dette innlegget, men jeg har ikke sett ett der det er flere egenskaper og de er innenfor et array. Og forresten er denne løsningen for ES6.

For illustrasjon, la oss si at vi har et array kalt person med objekter inni:

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

Så, du kan legge til en egenskap med tilsvarende verdi. La oss si at vi vil legge til et Språk med standardverdi EN.

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

Arrayet Person ville nå bli slik:

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

Svar #13

Jeg lette etter en løsning hvor jeg kan bruke dynamiske nøkkelnavn inne i objektdeklarasjonen (uten å bruke ES6-funksjoner som ... eller [key]: value)

Her er hva jeg kom opp med:

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

Det ser litt komplekst ut i begynnelsen, men det er egentlig enkelt. Vi bruker kommaoperatoren for å kjøre tre kommandoer på rad:

  1. obj={}: oppretter et nytt objekt og tildeler det til variabelen obj
  2. obj[field]=123: legger til et beregnet egenskapsnavn til obj
  3. obj: bruk obj-variabelen som resultatet av parentes-/kommalisten

Denne syntaksen kan brukes inne i en funksjonsparameter uten kravet om å eksplisitt deklarere obj-variabelen:

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

Noen variasjoner

"strict mode"-løsning:

Koden ovenfor fungerer ikke i strict mode fordi variabelen "obj" ikke er erklært.

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

ES2015-kode som bruker beregnede egenskapsnavn i initialiseringen:

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

Denne løsningen fungerer i alle moderne nettlesere (men ikke i IE, hvis jeg må nevne det)

Svært spak måte å bruke JSON.parse() på:

// Create a JSON string that is parsed instantly. Not recommended in most cases.
showObject( JSON.parse( '{"' + field +'":123}') );
// read: showObject( JSON.parse( '{"myDynamicfield":123}') );

Tillater spesialtegn i nøkler

Merk at du også kan bruke mellomrom og andre spesialtegn i beregnede egenskapsnavn (og også i JSON.parse).

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

Disse feltene kan ikke nås ved å bruke punktum (obj.my dynamic field :) er åpenbart syntaktisk ugyldig), men kun via hakeparentes-notasjon, det vil si obj['my dynamic field :)'] returnerer 123

Relaterte artikler