2014-01-22 4 views
4

내가이 같은 객체 (간체)을 말해봐 배열에 따라 객체 내부의 값을 가져 오거나 설정합니다.이 예제에서는 다음과 같습니다.액세스 중첩 된 객체는

options.boxes.size.x = somevalue; 

아이디어가 있으십니까?

답변

4

이렇게하기위한 쉬운 방법은 없습니다.

function getPath(obj, props) { 
    for(var i = 0; i < props.length; i++) { 
     if (props[i] in obj) { 
      obj = obj[props[i]]; 
     } else { 
      return; // not found 
     } 
    } 

    return obj; 
} 

function setPath(obj, value, props) { 
    for(var i = 0; i < props.length - 1; i++) { 
     if (props[i] in obj) { 
      obj = obj[props[i]]; 
     } else { 
      return; // not found 
     } 
    } 

    obj[props[i]] = value; 
} 

alert(getPath(options, names)); // 15 
setPath(options, 25, names); 
alert(getPath(options, names)); // 25 
+0

덕분에,이 마법처럼 작동합니다! –

4

는 그냥 names을 반복하면서 현재의 이름에 대한 다음 중첩 된 개체를 잡고 루프를 사용 : 당신은 당신의 자신의 방법을 쓸 필요가 것입니다. 거짓 값 또는 배열 끝이 루프를 중지해야합니다.

var obj = options; 
var i = 0; 

while (obj && i < names.length) 
    obj = obj[names[i++]]; 

또는 단순히 .reduce()

names.reduce(function(obj, name) { 
    return obj && obj[name]; 
}, options); 

를 사용 물론 당신이 이름을 지정하고 원하는 경우 기능을 다시 사용할 수 있습니다.

function toPropertyIn(obj, name) { 
    return obj && obj[name]; 
} 

names.reduce(toPropertyIn, options); 

는 게터/세터하려면 :

function nestedProp(obj, names, value) { 
    if (arguments.length > 1) 
     var setProp = names.pop(); 

    var res = names.reduce(function(obj, name) { 
     return obj && obj[name]; 
    }, options); 

    if (res && setProp !== undefined) 
     res[setProp] = value; 
    else 
     return res; 
} 


nestedProp(options, names, "foo"); // to set 

var val = nestedProp(options, names); // to get 
+1

두 번째 옵션이 재미있어 보입니다. 감사! –

+0

@LarsEbert : "세트"부분을 놓쳤습니다. 둘 다 처리 할 수있는 단일 함수로 업데이트되었습니다. –