2012-02-18 4 views
3

path.to.obj 문자열을 통해 myobject[path][to][obj]에 액세스하려면 어떻게해야합니까? 나는 'settingValue'settingObj[path][to][setting]으로 작성하는 함수 Settings.write('path.to.setting', 'settingValue')을 호출하려고합니다. eval()없이 어떻게해야합니까?도트 구문을 통한 액세스 개체

나는 아래의 사용자 중 한 명이 답변 한 것과 같은시기에 마침내 알아 냈습니다. 누군가가 관심을 가지면 어떻게 작동하는지에 대한 문서를 여기에 게시 할 것입니다.

(function(){ 
    var o = {}, c = window.Configure = {}; 

    c.write = function(p, d) 
    { 
     // Split the path to an array and assaign the object 
     // to a local variable 
     var ps = p.split('.'), co = o; 

     // Iterate over the paths, skipping the last one 
     for(var i = 0; i < ps.length - 1; i++) 
     { 
      // Grab the next path's value, creating an empty 
      // object if it does not exist 
      co = (co[ps[i]])? co[ps[i]] : co[ps[i]] = {}; 
     } 

     // Assign the value to the object's last path 
     co[ps[ps.length - 1]] = d; 
    } 

    c.read = function(p) 
    { 
     var ps = p.split('.'), co = o; 
     for(var i = 0; i < ps.length; i++) 
     { 
      co = (co[ps[i]])? co[ps[i]] : co[ps[i]] = {}; 
     } 
     return co; 
    } 
})(); 

내가 문제가있는 이유는 마지막 경로를 건너 뛰어야하기 때문입니다. 마지막 경로를 포함하면 결국 임의의 객체를 할당하게됩니다.

답변

3

당신은 그것에 대해 str.split()를 사용할 수 있습니다

path = pathString.split('.'); 
settingObj[path[0]][path[1]][path[2]] = settingValue; 

str.split()가 배열에 변수를 분리하는 것, 사용자가 지정한 문자의 위치에서 분할합니다.

이것은 물론 작업의 근원이며 적절한 입력을 가정합니다.

편집가 : 경로가 가변 길이 될 필요가 있기 때문에, 여기에 당신이 위에 표시 한 구문에서 편집 업데이트 버전입니다 :

(function(){ 
    var o = {}, c = window.Configure = {}; 

    c.write = function(p, d) 
    { 
     var ps = p.split('.'), co = o; 
     for(var i = 0; i < ps.length - 1; i++) 
     { 
      co = (co[ps[i]])? co[ps[i]] : co[ps[i]] = {}; 
     } 
     co[ps[ps.length-1]] = d; 
    } 

    c.read = function(p) 
    { 
     var ps = p.split('.'), co = o; 
     for(var i = 0; i < ps.length; i++) 
     { 
      co = (co[ps[i]])? co[ps[i]] : co[ps[i]] = {}; 
     } 
     return co; 
    } 

    c.write('path.to.property', 'setting'); 
    alert(c.read('path.to.property')); 
})(); 
+0

그러나 경로에 정확히 얼마나 많은 부분이 있는지 정확히 알지 못합니다. 2 일 수도 있고, 6 일 수도 있습니다. – LordZardeck

+0

제 잘못입니다. 나는 일종의 선재적 인 설정이라고 생각했습니다. 나는 코드를 여기에 넣었다 : http://jsfiddle.net/HVh7X/, 내가 편집을보기 전에 시작 했으니, 잠시 후에 나의 대답을 업데이트 할 것이다. – Rick

+0

롤, 그래, 그냥 알아 냈어.마지막 경로를 건너 뛸 필요가있어서, 그냥 임의의 값을 지정했기 때문입니다. 답을 수정하자마자 받아 들일 것입니다. – LordZardeck

2

귀하의 변수 co는 귀하의 재산에 대한 참조를 포함하지만, co 값을 co = p으로 업데이트하면 속성 값이 아닌 co 값을 덮어 쓰는 것입니다. 당신은 값을 설정하는 마지막 키에 대한 참조를 유지하고, 해당 키를 사용해야합니다 :

http://jsfiddle.net/gilly3/a2p8m/1/

c.write = function(p, d) 
{ 
    var ps = p.split('.'), co = o, key; 
    for(var i = 0; i < ps.length; i++) 
    { 
     if (key) 
     { 
      co = (key in co) ? co[key] : co[key] = {}; 
     } 
     key = ps[i]; 
    } 
    co[key] = d; 
    console.log(co); 
    console.log(o); 
} 

당신은 key in co 대신에 "truthy"체크를하는 사용할 수 있습니다. 그렇지 않은 경우 0 값을 {}으로 덮어 쓰는 동안 1 값이 유지됩니다. 그런 다음 다시 숫자로 속성을 쓸 수 없기 때문에 이러한 값 중 하나라도 위의 코드에 대한 런타임 오류가 발생합니다. 가장 좋은 방법은 typeof co[key]입니다.

co = co[key] && /object|function/.test(typeof co[key]) ? co[key] : co[key] = {}; 

내가 당신을 의심

을 (내가 내 대답에 조금 늦었 알고 있지만, 내 엄지 손가락 입력에 모든 노력을 가하고 후 그림, 나뿐만 아니라 어쨌든 그것을 포함 할 수 있습니다) 그룹화 오류가 발생했습니다. 나는이 테스트 것

co = (co[ps[i]] ? co[ps[i]] : co[ps[i]] = {}); 

자신을하지만 난 내 모바일에서 응답하고있어 그냥 엄지 손가락으로 입력 할 때 jsfiddle은 지루 : 줄의 끝으로 삼항 표현의 최종 괄호를 이동하십시오.

관련 문제