2014-01-29 1 views
0

그래서 주위를 둘러 보았다 그리고 내가하여 객체를 참조하려고 ..문자열 값으로 자바 스크립트 객체를 참조 - 평가 후면을 사용하지 않고는()

을하려고하고 일치 듯 아무것도 찾을 수 없습니다 캐릭터 라인 표현은, 사방하지만 나는 eval()를 사용하는 것이 나쁜 것을 볼 볼 - 사용하지 않고 할 수있는 방법을 찾을 수 있지만 eval()

그래서 내 사용 사례 : 나는 버튼을 데이터 속성이

;

data-original-data-object="window.app.myData.originalData" 

버튼은 내가 지금 window.app.myData.originalData

에서 열린 실물, 나는 내가 할 수있는 알고 접근 할 필요가 클릭하면 :

var dataObj = eval($(this).data('original-data-object')); 

비록이 작업을 수행하는 다른 방법이를 ?

window.app.myData.originalData에 저장된 데이터가 도움이되는 경우 JSON 개체입니다.

+0

이것은 eval이 허용되는 몇 가지 영역 중 하나입니다. 다른 방법은 [조회 기능] (https://gist.github.com/megawac/6162481#file-underscore-lookup-js)을 사용하는 것입니다. – megawac

+0

[내 eval을 사용하여 문자열을 함수?] (http://stackoverflow.com/questions/14396647/is-it-evil-to-use-eval-to-convert-a-string-to-a-function) – Bergi

답변

1

솔루션의 몇 가지 마음에 와서. 첫 번째 해결책은 @CD ..에서의 암시입니다. 두 번째는 eval을 안전하게 사용할 수 있도록 정규식을 통해 문자열을 속성 이름으로 제한하는 것입니다. 유효한 속성 이름에 문자열을 제한

값을 얻기 위해 window 객체를 순회 (더 평가)

function getValue(s) { 
    var keys = s.split("."), o = window, key, i, length, undef; 

    if (keys[0] === "window") { 
     keys.shift(); 
    } 

    for (i = 0, length = keys.length; i < length; i++) { 
     key = keys[i]; 

     if (!(key in o) || o[key] === null || o[key] === undef) { 
      throw new Error("Could not get value of " + s); 
     } 

     o = o[key]; 
    } 

    return o; 
} 

는 :

function getValue(s) { 
    var regex = /^[\w$][\w.]+$/, value; 

    if (regex.test(s)) { 
     try { 
      value = eval(s); 
     } 
     catch (error) { 
      throw new Error("Could not get value of " + s + " (" + error.message + ")"); 
     } 
    } 
    else { 
     throw new Error("Could not get value of " + s); 
    } 

    return value; 
} 

는 사용하지하려면

var x = getValue(this.getAttribute("data-original-data-object")); 

당신이 원하는 자바 스크립트를 임의로 실행할 수 있기 때문에 eval 사용을 피하기 위해 또는 제어 할 수 없습니다. 이 특별한 경우에는 원하는 문자열의 정확한 종류를 알 수 있습니다. 필자는 정규식을 사용하여 문자열에 점으로 구분 된 속성 이름이 포함되어 있는지 확인합니다. 이 상황에 작동하는지 잘 모르겠어요

var x = eval("window.foo"); 
var x = window.foo; 
+0

저는 두 번째 것을 좋아합니다 - 당신은'return value;'부분을 빠뜨렸다. 이것이 처음의 퍼포먼스와 어떻게 비교되는지, 그리고'eval()'- 어떤 생각입니까? – Darren

+0

반환 값을 원하십니까? 그건 나중에 추가 비용 것입니다! :) 내 대답이 업데이트되었습니다. 성능 차이가 무엇인지 잘 모르겠습니다. 'window.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r'의 값을 원한다면 성능이 거의 같을 것이라고 확신합니다. 자바 스크립트에서 벤치마킹하는 것은 어렵습니다. –

+0

오키, 그냥 궁금해. :) 당신의 상세한 답변을 주셔서 감사합니다 :) – Darren

0

어쨌든 구현중인 사이트/프로젝트에 피해를 줄 수있는 속성을 수정할 수 없다는 것을 보장한다면 아무런 문제가 없습니다. 이처럼

+0

단점은 속성 HTML로되어 있기 때문에 콘솔을 망칠 경우 문제가 발생할 수 있습니다.이 경우 공개 사이트가 아닙니다. – Darren

+0

@Darren : 그게 무슨 소리 야? 콘솔을 망치면 항상 문제가 발생할 수 있습니다. – Bergi

+0

나중에 'data-original-data-object'에 dodgy-code가 추가 될 가능성을 열어 놓았는지 잘 모르겠다. 이 경우에는 매우 드문 시나리오입니다. – Darren

3

는 :

var obj = (function(str){ 
    var arr = str.split('.'); 

    if (arr[0] === 'window'){ 
    arr.shift(); 
    } 

    return arr.reduce(function(a, b){ 
    return a[b]; 
    }, window); 

}("window.app.myData.originalData")) 
+0

왜 forEach를 사용합니까? 적절한 방법은'return array.reduce (function (result, part) {return result [part];}, window)'입니다. -oops, 편집을 보지 못했습니다 :-) – Bergi

+0

실제 객체에 접근하는 방법은? var obj =? – mplungjan

+0

예제에서 "originalData"의 값을 어떻게 설정 하시겠습니까? – adam0101

0

하지만 평가는 "window.app를 추가 할 수 있습니다 피하는 간단한 해결책 : 보안 말하기, 코드의 두 라인 사이에는 차이가 없다. 범위에 남아있는 객체의 속성으로 JSON 데이터를 사용하여 "myData.originalData"를 만듭니다.같은

뭔가 :

var exampleData = { id:1, content:"..." }; 

var dataStore = { "window.app.myData.originalData": exampleData }; 

그런 다음, 클릭 처리기 :이 경우

var retrievedData = dataStore[$(this).data('original-data-object')]; // uses "window.app.myData.originalData" to retrieve exampleData 

, 당신은 때문에의 브래킷 표기법을 사용하여 데이터에 액세스해야합니다. 특성 이름의 문자. 그러나이 방법은 eval을 사용하는 것보다 빠르고 안전해야합니다.

+0

이 경우에는 다른 개체에 대한 참조를 저장하는 데 더 많은 변수가 필요하지만 작동합니다. 앱이 커지면서 오버 헤드가 너무 적습니다. 그런 다음 객체 'window.app.myData.originalData'가 이름 변경을 거친다면, 그것을 바꿀 수있는 곳이 더 많습니다. 고마워요 :) – Darren

+0

아마도 jQuery를 사용하여 dataStore 객체를 미리 동적으로 생성하여 속성 이름의 데이터 속성을 검색 할 수 있습니다. 그러면 객체의 속성을 유지할 필요가 줄어들고 이름 변경으로 인해 문제가 발생하지 않습니다. 그러나 정확한 요구 사항을 모른 채이 방법이 당신에게 이상적이지 않을 수도 있음을 인정합니다. – polyslush