programing

동적으로 명명 된 속성을 JavaScript 개체에 추가 할 수 있습니까?

nasanasas 2020. 9. 30. 10:56
반응형

동적으로 명명 된 속성을 JavaScript 개체에 추가 할 수 있습니까?


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?

예.

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

data["PropertyD"] = 4;

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


승리를위한 ES6!

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

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

로그 data하면 다음을 얻을 수 있습니다.

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

이것은 새로운 계산 된 속성 구문과 템플릿 리터럴을 사용 합니다.


네 가능합니다. 가정 :

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

어느 한 쪽:

data[propertyName] = propertyValue;

또는

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

첫 번째 방법이 선호됩니다. eval ()은 사용자가 제공 한 값을 사용하는 경우 명백한 보안 문제가 있으므로 피할 수 있으면 사용하지 마십시오. 그러나 그것이 존재하고 무엇을 할 수 있는지 알 가치가 있습니다.

이것을 다음과 같이 참조 할 수 있습니다.

alert(data.someProperty);

또는

data(data["someProperty"]);

또는

alert(data[propertyName]);

질문에 대한 답이 완벽하다는 것을 알고 있지만 새 속성을 추가하는 또 다른 방법을 찾았으며이를 공유하고 싶었습니다.

기능을 사용할 수 있습니다 Object.defineProperty()

Mozilla 개발자 네트워크 에서 발견

예:

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

여기에서 표기법을 사용합니다.

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'

이전의 모든 답변 외에도 계산 된 속성 이름 (ECMAScript 6)을 사용 하여 미래 에 동적 속성 이름을 작성하는 방법이 궁금한 경우 방법은 다음과 같습니다.

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

personIndex[ personId ]; // "John Doe"

참조 : ECMAScript 6 이해-Nickolas Zakas


점 표기법을 사용하여 원하는만큼 속성을 추가 할 수 있습니다.

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

또는 :

data[newattribute] = somevalue

동적 키의 경우.


위의 abeing의 답변에 추가되었습니다. 아래와 같이 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


ES6는 계산 된 속성 이름을 도입하여 다음을 수행 할 수 있습니다.

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

아래 옵션 중 일부를 사용하여 속성을 동적으로 추가 할 수 있습니다.

당신의 예에서 :

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

다음 두 가지 방법으로 동적 값을 사용하여 속성을 정의 할 수 있습니다.

data.key = value;

또는

data['key'] = value;

훨씬 더 .. 키가 동적 인 경우 다음과 함께 Object 클래스를 사용하여 정의 할 수 있습니다.

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

여기서 data 는 객체이고 key 는 키 이름 을 저장할 변수 이고 value 을 저장할 변수입니다.

이게 도움이 되길 바란다!


이 게시물에 대한 몇 가지 답변이 이미 있다는 것을 알고 있지만 여러 속성이 있고 배열 내에있는 답변은 본 적이 없습니다. 그런데이 솔루션은 ES6 용입니다.

예를 들어 내부에 개체가있는 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"}]

가장 간단하고 휴대하기 쉬운 방법은 다음과 같습니다.

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

#abeing 답변을 기반으로!


객체를 포함하는 동적 문자열 이름 (예 : 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와 동일합니다.


. (dot) 메서드를 사용하여 기존 객체에 속성을 추가 할 때 주의하십시오 .

(.dot) method of adding a property to the object should only be used if you know the 'key' beforehand otherwise use the [bracket] method.

Example:

   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 }

Note the problem in the end of console log - 'key: 1999' instead of Property6: 6, Property7: 7,.........,Property1999: 1999. So the best way of adding dynamically created property is the [bracket] method.


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

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

Definitely. Think of it as a dictionary or associative array. You can add to it at any point.

참고URL : https://stackoverflow.com/questions/1184123/is-it-possible-to-add-dynamically-named-properties-to-javascript-object

반응형