programing

동적으로 계산된 이름으로 개체 속성 액세스

closeapi 2023. 6. 15. 21:53
반응형

동적으로 계산된 이름으로 개체 속성 액세스

동적 이름을 사용하여 개체의 속성에 액세스하려고 합니다.이것이 가능합니까?

const something = { bar: "Foobar!" };
const foo = 'bar';
something.foo; // The idea is to access something.bar, getting "Foobar!"

개체의 속성에 액세스하는가지 방법은 다음과 같습니다.

  • 표기법: 점표법기:something.bar
  • 표기법: 괄호표법기:something['bar']

괄호 사이의 값은 임의의 식을 사용할 수 있습니다.따라서 속성 이름이 변수에 저장된 경우 괄호 표기법을 사용해야 합니다.

var something = {
  bar: 'foo'
};
var foo = 'bar';

// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)

이것이 제 해결책입니다.

function resolve(path, obj) {
    return path.split('.').reduce(function(prev, curr) {
        return prev ? prev[curr] : null
    }, obj || self)
}

사용 예:

resolve("document.body.style.width")
// or
resolve("style.width", document.body)
// or even use array indexes
// (someObject has been defined in the question)
resolve("part.0.size", someObject) 
// returns null when intermediate properties are not defined:
resolve('properties.that.do.not.exist', {hello:'world'})

Javascript에서 다음과 같이 액세스할 수 있습니다.

  • 표기법 - 점표법기 -foo.bar
  • - 대호괄 -foo[someVar]또는foo["string"]

그러나 두 번째 경우에만 동적으로 속성에 액세스할 수 있습니다.

var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}

var name = "pName"
var num  = 1;

foo[name + num]; // 1

// -- 

var a = 2;
var b = 1;
var c = "foo";

foo[name + a][b][c]; // bar

다음은 두 문자열을 연결하여 동적으로 생성된 속성 이름을 사용하여 개체의 속성에 액세스하는 방법에 대한 ES6 예입니다.

var suffix = " name";

var person = {
    ["first" + suffix]: "Nicholas",
    ["last" + suffix]: "Zakas"
};

console.log(person["first name"]);      // "Nicholas"
console.log(person["last name"]);       // "Zakas"

이를 계산된 속성 이름이라고 합니다.

여러분은 이것을 꽤 다양한 방법으로 달성할 수 있습니다.

let foo = {
    bar: 'Hello World'
};

foo.bar;
foo['bar'];

괄호 표기법은 변수를 기반으로 속성에 액세스할 수 있기 때문에 특히 강력합니다.

let foo = {
    bar: 'Hello World'
};

let prop = 'bar';

foo[prop];

이는 개체의 모든 속성을 루프하도록 확장할 수 있습니다.이는 ...의 ...와 같은 새로운 JavaScript 구조 때문에 중복된 것으로 보일 수 있지만 사용 사례를 설명하는 데 도움이 됩니다.

let foo = {
    bar: 'Hello World',
    baz: 'How are you doing?',
    last: 'Quite alright'
};

for (let prop in foo.getOwnPropertyNames()) {
    console.log(foo[prop]);
}

점 및 대괄호 표기법은 중첩된 객체에 대해서도 예상대로 작동합니다.

let foo = {
    bar: {
        baz: 'Hello World'
    }
};

foo.bar.baz;
foo['bar']['baz'];
foo.bar['baz'];
foo['bar'].baz;

객체 파괴

또한 객체의 속성에 액세스하기 위한 수단으로 객체 파괴를 고려할 수 있지만 다음과 같습니다.

let foo = {
    bar: 'Hello World',
    baz: 'How are you doing?',
    last: 'Quite alright'
};

let prop = 'last';
let { bar, baz, [prop]: customName } = foo;

// bar = 'Hello World'
// baz = 'How are you doing?'
// customName = 'Quite alright'

Lodashget을 사용하여 이렇게 할 수 있습니다.

_.get(object, 'a[0].b.c');

업데이트됨

에 액세스하는 은 객의루속쉽액수있다습니할세스체게성트로 할 수 .obj[variable]하지만 둥지를 틀면 일이 복잡해집니다.하지 않기 는 이미작성코작드성않지는다좋것습니이하된을 사용하는 것이 .lodash.get.

// Accessing root property
var rootProp = 'rootPropert';
_.get(object, rootProp, defaultValue);

// Accessing nested property
var listOfNestedProperties = [var1, var2];
_.get(object, listOfNestedProperties);

lodashget은 다양한 방법으로 사용될 수 있습니다. lodash.get 문서

속성에 동적으로 액세스하려면 대괄호를 사용합니다. []다음과 같이:

const something = { bar: "Foobar!" };
const userInput = 'bar';
console.log(something[userInput])

그 문제는

그 해결책에는 중요한 고트치야가 있습니다! (다른 답변들이 아직 이 문제를 제기하지 않은 것에 놀랐습니다.)종종 상속된 속성을 가져오지 않고 해당 개체에 추가한 속성에만 액세스하려는 경우가 있습니다.

다음은 이 문제에 대한 예시입니다.여기 순진해 보이는 프로그램이 있습니다만, 미묘한 버그가 있습니다. 찾을 수 있습니까?

const agesOfUsers = { sam: 16, sally: 22 }
const username = prompt('Enter a username:')
if (agesOfUsers[username] !== undefined) {
  console.log(`${username} is ${agesOfUsers[username]} years old`)
} else {
  console.log(`${username} is not found`)
}

사용자 이름을 입력하라는 메시지가 표시되면 "toString"을 사용자 이름으로 제공하면 "toString is function to String() {[native code] } years"라는 메시지가 표시됩니다.는 문는입니다.agesOfUsers는 개체이므로 다음과 같은 특정 속성을 자동으로 상속합니다..toString()기본 Object 클래스에서 가져옵니다.여기에서 모든 개체가 상속하는 속성의 전체 목록을 확인할 수 있습니다.

솔루션

  1. 대신 지도 데이터 구조를 사용합니다.지도의 저장된 내용은 프로토타입 문제를 겪지 않으므로 이 문제에 대한 깨끗한 해결책을 제공합니다.

const agesOfUsers = new Map()
agesOfUsers.set('sam', 16)
agesOfUsers.set('sally', 2)
console.log(agesOfUsers.get('sam')) // 16

  

  1. 기본 프로토타입 대신 null 프로토타입이 있는 개체를 사용합니다.사용할 수 있습니다.Object.create(null)이러한 개체를 생성합니다.이런 종류의 개체는 이러한 프로토타입 문제로 인해 문제가 발생하지 않습니다. 왜냐하면 어떤 것도 상속하지 않는 방식으로 명시적으로 생성했기 때문입니다.

const agesOfUsers = Object.create(null)
agesOfUsers.sam = 16
agesOfUsers.sally = 22;
console.log(agesOfUsers['sam']) // 16
console.log(agesOfUsers['toString']) // undefined - toString was not inherited

  

  1. 사용할 수 있습니다.Object.hasOwn(yourObj, attrName)먼저 액세스하려는 동적 키가 개체에 직접 있고 상속되지 않았는지 확인합니다(자세한 내용은 여기 참조).이 기능은 비교적 최신 기능이므로 호환성 표를 확인한 후 코드에 넣으십시오.전에Object.hasOwn(yourObj, attrName)당신은 이와 같은 효과를 얻을 수 있을 것을 통해.Object.prototype.hasOwnProperty.call(yourObj, attrName)때때다로을음사코볼드수있습다니를여용하▁using다▁sometimes니▁code있을 사용하는 코드가 보일 수도 있습니다.yourObj.hasOwnProperty(attrName)때때로 효과가 있지만 여기서 읽을 수 있는 몇 가지 함정이 있습니다.

// Try entering the property name "toString",
// you'll see it gets handled correctly.
const user = { name: 'sam', age: 16 }
const propName = prompt('Enter a property name:')
if (Object.hasOwn(user, propName)) {
  console.log(`${propName} = ${user[propName]}`)
} else {
  console.log(`${propName} is not found`)
}

  1. 사용하려는 키가 상속된 속성의 이름이 될 수 없다는 것을 알고 있는 경우(예: 해당 키가 숫자이거나 모두 같은 접두사를 사용하는 등) 원래 솔루션을 사용을 선택할 수 있습니다.

객체 속성의 "주소"를 다른 함수에 데이터로 전달하고 객체를 채우고(AJAX로) 주소 배열에서 조회하고 다른 함수에 표시하고 싶다고 생각한 경우를 우연히 발견했습니다.저는 현악 곡예를 하지 않고는 점 표기법을 사용할 수 없기 때문에 배열을 대신 통과하는 것이 좋을 것이라고 생각했습니다.저는 결국 다른 일을 하게 되었지만, 이 게시물과 관련이 있는 것 같았습니다.

다음은 제가 원하는 데이터와 같은 언어 파일 개체의 샘플입니다.

const locs = {
  "audioPlayer": {
    "controls": {
      "start": "start",
      "stop": "stop"
    },
    "heading": "Use controls to start and stop audio."
  }
}

저는 ["audioPlayer", "controls", "stop"]과 같은 배열을 전달하여 언어 텍스트에 액세스할 수 있게 하고 싶었습니다. 이 경우 "stop".

저는 "가장 구체적이지 않은"(첫 번째) 주소 매개 변수를 찾아 반환된 개체를 자신에게 재할당하는 이 작은 함수를 만들었습니다.그런 다음 가장 구체적인 주소 매개 변수가 있는 경우 이 매개 변수를 검색할 준비가 됩니다.

function getText(selectionArray, obj) {
  selectionArray.forEach(key => {
    obj = obj[key];
  });
  return obj;
}

용도:

/* returns 'stop' */
console.log(getText(["audioPlayer", "controls", "stop"], locs)); 

/* returns 'use controls to start and stop audio.' */
console.log(getText(["audioPlayer", "heading"], locs)); 

ES5 // 깊이 내포된 변수 검사

이 간단한 코드 조각은 각 변수를 검사하지 않고도 깊이 중첩된 변수/값의 존재를 확인할 수 있습니다.

var getValue = function( s, context ){
    return Function.call( context || null, 'return ' + s )();
}

예 - 깊이 중첩된 개체 배열:

a = [ 
    {
      b : [
          {
             a : 1,
             b : [
                 {
                    c : 1,
                    d : 2   // we want to check for this
                 }
             ]
           }
      ]
    } 
]

다음 대신:

if(a && a[0] && a[0].b && a[0].b[0] && a[0].b[0].b && a[0].b[0].b[0] && a[0].b[0].b[0].d && a[0].b[0].b[0].d == 2 )  // true

이제 할 수 있습니다.

if( getValue('a[0].b[0].b[0].d') == 2 ) // true

건배!

다른 사람들은 이미 '도트'와 '제곱' 구문을 언급했기 때문에 저는 비슷한 방식으로 함수에 액세스하고 매개 변수를 보내는 것에 대해 다루고 싶습니다.

코드 jfiddle

var obj = {method:function(p1,p2,p3){console.log("method:",arguments)}}

var str = "method('p1', 'p2', 'p3');"

var match = str.match(/^\s*(\S+)\((.*)\);\s*$/);

var func = match[1]
var parameters = match[2].split(',');
for(var i = 0; i < parameters.length; ++i) {
  // clean up param begninning
    parameters[i] = parameters[i].replace(/^\s*['"]?/,'');
  // clean up param end
  parameters[i] = parameters[i].replace(/['"]?\s*$/,'');
}

obj[func](parameters); // sends parameters as array
obj[func].apply(this, parameters); // sends parameters as individual values

제가 얼마 전에 이 주제에 대해 중복되는 질문을 던졌는데, 과도한 연구 끝에, 그리고 여기 있어야 할 많은 정보가 누락된 것을 보고, 저는 제가 이 오래된 게시물에 추가할 가치가 있다고 생각합니다.

  • 먼저 부동산의 가치를 얻고 동적 변수에 저장하는 몇 가지 방법이 있다는 것을 설명하고 싶습니다.IMHO의 가장 일반적이고 쉬운 방법은 다음과 같습니다.
let properyValue = element.style['enter-a-property'];

그러나 스타일시트를 통해 할당된 속성 값에는 적용되지 않기 때문에 이 경로를 거의 사용하지 않습니다.예를 들어, 저는 약간의 유사 코드로 시연해 보겠습니다.

 let elem = document.getElementById('someDiv');
 let cssProp = elem.style['width'];

위의 코드 예제를 사용하면, '엘렘' 변수에 저장된 div 요소의 너비 속성이 HTML 태그 내부에서 스타일이 아닌 CSS 스타일 시트에서 스타일이 지정된 경우, cssProp 변수 내부에 저장된 정의되지 않은 반환 값을 얻을 수 있습니다.정의되지 않은 값은 올바른 값을 얻으려면 CSS 스타일시트 내에 작성된 코드가 값을 얻기 위해 계산되어야 하기 때문에 발생합니다. 따라서 스타일시트 내에 있는 값의 속성 값을 계산하는 방법을 사용해야 합니다.

  • 이제 getComputedStyle() 메서드를 사용합니다!
function getCssProp(){
  let ele = document.getElementById("test");
  let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}

W3Schools getComputedValue Doc 이것은 좋은 예를 제공하고 이것을 가지고 놀 수 있게 해줍니다. 그러나 Mozilla CSS getComputedValue Doc 링크는 getComputedValue 기능에 대해 자세히 설명하고 있으며, 이 주제에 대해 완전히 명확하지 않은 개발자 지망생이라면 누구나 읽어야 합니다.

  • 참고로 getComputedValue 메서드는 설정되지 않고 가져오기만 합니다.이것은 분명히 큰 단점이지만, 표준 자바스크립트는 아니지만 CSS 스타일시트에서 가져올 뿐만 아니라 값을 설정하는 방법이 있습니다.JQuery 메서드...
$(selector).css(property,value)

...얻기도 하고, 잡기도 합니다.이것이 제가 사용하는 것입니다. 유일한 단점은 당신이 JQuery를 알게 되었다는 것입니다. 하지만 이것은 솔직히 모든 자바스크립트 개발자들이 JQuery를 배워야 하는 많은 좋은 이유 중 하나입니다. 이것은 삶을 쉽게 만들고, 표준 자바스크립트에서는 사용할 수 없는 방법을 제공합니다.이것이 누군가에게 도움이 되기를 바랍니다!

중첩 변수의 값을 설정하려는 사용자는 다음과 같이 설정할 수 있습니다.

const _ = require('lodash'); //import lodash module

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.set(object, 'a[0].b.c', 4);
console.log(object.a[0].b.c);
// => 4

설명서: https://lodash.com/docs/4.17.15#set

또한 값을 얻고자 하는 경우 설명서: https://lodash.com/docs/4.17.15#get

괄호 표기법을 사용하여 개체의 속성에 동적으로 액세스할 수 있습니다.은 이 이것은렇이게보것입다니일.obj[yourKey] 그러나 JavaScript 개체는 동적으로 업데이트되거나 읽히도록 설계되지 않았습니다.이들은 초기화 시 정의됩니다.

으로 하고 액세스하고 key value당신은 대신 지도를 사용해야 합니다.

const yourKey = 'yourKey';

// initialise it with the value
const map1 = new Map([
  ['yourKey', 'yourValue']
]);

// initialise empty then dynamically assign
const map2 = new Map();
map2.set(yourKey, 'yourValue');

console.log(map1.get(yourKey));
console.log(map2.get(yourKey));

데모 개체 예제

let obj = {
    name: {
        first_name: "Bugs",
        last_name: "Founder",
        role: "Programmer"
    }
}

값을 가져오기 위한 점선 문자열 키

let key = "name.first_name"

기능.

const getValueByDottedKeys = (obj, strKey)=>{
    let keys = strKey.split(".")
    let value = obj[keys[0]];   
    for(let i=1;i<keys.length;i++){
        value = value[keys[i]]
    }
    return value
}

getValueByDotedKeys 함수 호출

value = getValueByDottedKeys(obj, key)
console.log(value)

산출량

Bugs

const getValueByDottedKeys = (obj, strKey)=>{
    let keys = strKey.split(".")
    let value = obj[keys[0]];   
    for(let i=1;i<keys.length;i++){
        value = value[keys[i]]
    }
    return value
}

let obj = {
    name: {
        first_name: "Bugs",
        last_name: "Founder",
        role: "Programmer"
    }
}

let key = "name.first_name"

value = getValueByDottedKeys(obj, key)
console.log(value)

저도 같은 문제에 부딪혔지만 중첩된 속성을 처리할 때 lodash 모듈이 제한됩니다.저는 재귀적인 후손 파서의 아이디어를 따라 더 일반적인 해결책을 썼습니다.이 솔루션은 다음 Gist에서 사용할 수 있습니다.

재귀 하강 개체 참조 해제

문자열을 사용하지 않고 참조로 개체 찾기 전달한 개체가 복제되었는지 확인하십시오. 이를 위해 lodash에서 cloneDeep을 사용합니다.

사물이 처럼 보이는 경우

const obj = {data: ['an Object',{person: {name: {first:'nick', last:'gray'} }]

경로가 다음과 같습니다.

const objectPath = ['data',1,'person',name','last']

그런 다음 아래 메소드를 호출하면 주어진 경로별로 하위 개체를 반환합니다.

const child = findObjectByPath(obj, objectPath)
alert( child) // alerts "last"


const findObjectByPath = (objectIn: any, path: any[]) => {
    let obj = objectIn
    for (let i = 0; i <= path.length - 1; i++) {
        const item = path[i]
        // keep going up to the next parent
        obj = obj[item] // this is by reference
    }
    return obj
}

사용할 수 있습니다.getter

getter Docs

개체 내부에 문제의 속성이 있는지 확인하고 없으면 창에서 속성을 가져옵니다.

const something = {
    get: (n) => this.n || something.n || window[n]
};

당신은 야합다니해를 사용해야 .JSON.parsehttps://www.w3schools.com/js/js_json_parse.asp 을 살펴보십시오.

const obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}')
console.log(obj.name)
console.log(obj.age)

언급URL : https://stackoverflow.com/questions/4244896/accessing-an-object-property-with-a-dynamically-computed-name

반응형