변수를 사용하여 객체 속성에 동적으로 액세스


721

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

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

답변:


958

객체의 속성액세스하는 방법 에는 두 가지가 있습니다 .

  • 점 표기법 : something.bar
  • 브라켓 표기법 : something['bar']

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

var foo = 'bar';
something[foo];
// both x = something[foo] and something[foo] = x work as expected

34
주의 : 자바 스크립트 컴파일러는 문자열의 이름을 바꾸지 않지만 객체 속성의 이름을 바꾸기 때문에 오류가 발생합니다.
chacham15

6
이것이 가능한 이유에 대한 추가 정보 : JS 객체는 연관 배열이므로 그 이유입니다. 추가 자료 : quirksmode.org/js/associative.html stackoverflow.com/questions/14031368/…
Sudhanshu Mishra

@dotnetguy 아니에요. 배열은 일반 JS 객체 프로토 타입에서 상속되는 객체이므로 일반 객체와 마찬가지로 속성을 추가 할 수 있습니다. 'associative'행동은 배열과 같은 객체보다 더 유사합니다. 간단한 색인으로 '연관'버전을 반복 할 수 없으므로 배열과 같은 동작을 표시하지 않습니다. 'associative'배열을 {} 또는 []로 정의하고 임의의 속성 액세스에 관한 한 두 경우 모두 동일하게 취급 할 수 있습니다.
정복 된 웜뱃

3
@VanquishedWombat 귀하의 이의가 무엇인지 확실하지 않습니까? JS 객체가 배열이라고 말하지 않았습니까?
Sudhanshu Mishra

1
이 답변은
과장된

104

이것은 내 솔루션입니다.

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'})


2
공백을 사용하여 대괄호 표기법 및 속성 이름을 사용하고 입력을 검증 할 수있는 고급 버전을 만들도록 영감을주었습니다. it.knightnet.org.uk/kb/node-js/get-properties
Julian Knight

나는이 솔루션을 좋아한다. 그러나 원래 객체의 값을 수정하려고하는데 함수가 객체의 하위 복사본을 반환하는 것 같습니다. 반환 된 객체를 수정하여 원본을 수정하도록 변경할 수 있습니까?
Eagle 1

40

자바 스크립트에서 다음을 사용하여 액세스 할 수 있습니다.

  • 점 표기법- 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

4
이전 개발자는 대괄호를 사용하지 않고 점 표기법으로 정적으로 액세스 된 객체 속성을 사용하기 때문에 2,000 줄의 if 문을 쳐다보고 있습니다. 승인자가 7 인 승인 프로세스 앱용이며 단계가 모두 동일합니다. / rip
채드

26

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

var suffix = " name";

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

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

이것을 계산 된 속성 이름 이라고 합니다


16

몇 가지 다른 방법으로이를 달성 할 수 있습니다.

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

foo.bar;
foo['bar'];

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

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

let prop = 'bar';

foo[prop];

이것은 객체의 모든 속성을 반복하도록 확장 될 수 있습니다. for ... of ...와 같은 최신 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'

11

Lodash get을 사용하여 이와 같이 할 수 있습니다

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

이 옵션이 유일한 옵션 인 깊은 중첩 개체 조회와 같은 많은 상황이 있습니다.
Jonathan Kempf 2016 년

8

업데이트

아래 의견을 고려하여 동의했습니다. 평가는 피해야한다.

를 사용하면 객체의 루트 속성에 쉽게 액세스 할 수 obj[variable]있지만 중첩되는 것은 복잡합니다. 이미 작성된 코드를 작성하지 말고 사용하는 것이 좋습니다 lodash.get.

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

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

Lodash get은 다양한 방법으로 사용할 수 있습니다. 여기 lodash.get 문서에 대한 링크가 있습니다.


4
eval가능할 때마다 사용하지 않는 것이 가장 좋습니다 . stackoverflow.com/questions/86513/…
누가

8
eval속성에 액세스하는 것만 큼 사소한 것을 사용 하는 것은 어느 정도의 상황에서 일반적으로 과잉이며 거의 권장되지 않습니다. "고장"이란 무엇입니까? obj['nested']['test']매우 잘 작동하며 문자열에 코드를 포함시킬 필요가 없습니다.
Kyll

3
eval은 세 배 이상 느리다. 초보자에게 나쁜 습관을 가르 칠 수 있기 때문에 이것을 추천하지 않는다. 나는 사용 obj['nested']['value']-아이들을 기억, 평가는 악하다!
jaggedsoft

1
@Luke 그는 이제 Lodash _.get를 테이블 에 데려오고 싶은 유일한 사람 입니다. 나는이 대답이 이제 downvotes 대신 upvotes 가치가 있다고 생각합니다. 과잉 일 수도 있지만 존재한다는 것을 아는 것이 좋습니다.
Emile Bergeron

1
lodash를 소개해 주셔서 감사합니다. 구글에 의해 객체의 깊이를 설정하는 방법을 찾고 여기에 왔으며 _.set 메소드를 사용했습니다 (위와 동일하지만 설정할 값에 대한 추가 논쟁과 함께).
TPHughes

5

속성에 동적으로 액세스해야 할 때마다 "."가 아닌 속성에 액세스하려면 대괄호를 사용해야합니다. 연산자
구문 : object [propery}

const something = { bar: "Foobar!" };
const foo = 'bar';
// something.foo; -- not correct way at it is expecting foo as proprty in  something={ foo: "value"};
// correct way is  something[foo]
alert( something[foo])


4

객체 속성의 "주소"를 데이터로 다른 함수에 전달하고 객체를 AJAX로 채우고 주소 배열에서 조회하고 다른 함수에 표시하려고 한다고 생각한 사례를 발견했습니다 . 문자열 곡예를 수행하지 않고 도트 표기법을 사용할 수 없으므로 배열을 대신 전달하는 것이 좋을 것이라고 생각했습니다. 어쨌든 다른 일을 끝내었지만이 게시물과 관련이있는 것 같습니다.

다음은 데이터를 원하는 언어 파일 객체의 샘플입니다.

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

이 경우 언어 텍스트 "stop"에 액세스하기 위해 [ "audioPlayer", "controls", "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)); 

2

이 함수에 매개 변수를 전달해야 할 때도 흥미로워집니다.

코드 jsfiddle

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

1

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

건배!


1
해결책이 eval을 사용하는 경우 백만 개의 다른 문제가 발생했습니다.
Rodrigo Leite

@RodrigoLeite 좋아, 그래서 적어도 하나를주는 문제가되지 않을 것입니다 ...


1
@RodrigoLeite 나는 그것을 읽고, 사용하는 솔루션을 업데이트 한 Function대신

0

나는이 주제에 대해 잠시 동안 중복 된 질문을했고 과도한 연구를 거쳐 여기에 있어야 할 많은 정보가 누락 된 것을 보았을 때이 오래된 게시물에 추가 할 가치가 있다고 생각합니다.

  • 먼저 속성의 값을 가져 와서 동적 변수에 저장하는 몇 가지 방법이 있다고 설명하고 싶습니다. 가장 인기 있고 가장 쉬운 IMHO 방법은 다음과 같습니다.
let properyValue = element.style['enter-a-property'];

그러나 스타일 시트를 통해 할당 된 속성 값에서는 작동하지 않기 때문에이 경로를 거의 사용하지 않습니다. 예제를 제공하기 위해 약간의 의사 코드를 보여 드리겠습니다.

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

위의 코드 예제를 사용하십시오. 'elem'변수에 저장된 div 요소의 width 속성이 CSS 스타일 시트에서 스타일이 지정되고 HTML 태그 내부에서 스타일이 지정되지 않은 경우 undefined의 반환 값을 얻을 수 있습니다. cssProp 변수의 정의되지 않은 값은 올바른 값을 얻기 위해 순서대로 발생하기 때문에 CSS Style-Sheet 안에 작성된 코드는 순서대로 계산되어야합니다. 값이 스타일 시트 내에있는 속성 값을 계산하는 방법을 사용해야합니다.

  • 이제 getComputedStyle () 메소드!
function getCssProp(){
  let ele = document.getElementById("test");
  let cssProp = window.getComputedStyle(ele,null).getPropertyValue("width");
}

W3Schools getComputedValue Doc 이 예제는 좋은 예제를 제공하지만이 링크를 사용하여 재생할 수 있습니다. 그러나이 링크 Mozilla CSS getComputedValue 문서 는 getComputedValue 함수에 대해 자세히 설명하며이 주제에 대해 완전히 명확하지 않은 주목받는 개발자가 읽어야합니다.

  • 참고로 getComputedValue 메소드는 설정 만하지 않고 가져옵니다. 이것은 명백한 주요 단점이지만, 표준 Javascript는 아니지만 CSS 스타일 시트에서 가져오고 값을 설정하는 방법이 있습니다. JQuery 메소드 ...
$(selector).css(property,value)

... 얻고 설정합니다. 필자가 사용하는 유일한 단점은 JQuery를 알아야한다는 것입니다. 그러나 이것은 모든 Javascript 개발자가 JQuery를 배워야하는 매우 많은 좋은 이유 중 하나입니다. 표준 자바 스크립트에서는 사용할 수 없습니다. 이것이 누군가를 돕기를 바랍니다!




-4
const something = { bar: "Foobar!" };
const foo = 'bar';

something[\`${foo}\`];

7
왜 지구상에서 그렇게하겠습니까? 귀하 foo는 이미 문자열 `${foo}`이므로과 정확히 동일합니다 foo. (또한 코드에는 거기에 속하지 않는 추가 백 슬래시가있는 것 같습니다. 그러나 구문 오류를 수정하더라도 여전히 의미가 없습니다.)
Ilmari Karonen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.