공부한것들을 정리하는 블로그 입니다.
javascript eval 함수 본문
eval 함수의 장점이자 단점은, 스크립트의 실행을 런타임에서 결정한다는 것입니다.(사실상 단점..)
이 함수는 임의의 문자열을 받아 자바스크립트 코드로 실행합니다.
만약 문제의 코드를 사전에 알 수 있다면(즉 런타임에 결정되는 게 아니라면) eval()을 쓸 필요가 없습니다.
코드가 런타임에 동적으로 생성된다면 대개 eval() 없이 목표를 달성할 수 있는 더 나은 방법이 존재합니다.
다음 예제는 eval() 은 그 자신의 바깥쪽 유효범위에 접근하고 수정을 가할 수 있는 반면, Function 은 그럴 수 없습니다.(Function 을 사용하는 것과 new Function 은 동일하다)
예제) 유효범위 오염
(function () { var local = 1; eval('local = 3; console.log(local);'); // 3 이 기록된다. console.log(local); // 유효범위를 오염시켜 3 이 기록된다. })(); (function () { var local = 1; Function('console.log(typeof local);')(); // undefined 가 기록된다. })();
실전예제
예제) 본인이 직접 사용한 코드
UI 화면
script(원본)
function btnSameAsPlan_OnClick(obj) { // 결과인 경우 if(planYn == "N"){ //계획/실적공수는 copy 안함 //계획/실적공수 //edtRsltMh.Text = edtPlanMh.Text; //edtRsltMh.Value = edtPlanMh.Value; //난이도 //신규여부 //대외 인터페이스 연관 //고유식별정보작업유무 //PC저장고유식별번호포함파일삭제확인 var strCmbPlanApp = "cmbPlanApp"; var strCmbRsltApp = "cmbRsltApp"; for(var i=1 ; i-1 < 5 ; i++){ eval(strCmbRsltApp + ToString(i)).Value = eval(strCmbPlanApp + ToString(i)).Value; } //합계 edtRsltSum.Text = edtPlanSum.Text; //변경CI var strEdtPlan_ = "edtPlan_"; var strEdtRslt_ = "edtRslt_"; for(var i=1 ; i-1 < 4 ; i++){ eval(strEdtRslt_ + ToString(i)).Value = eval(strEdtPlan_ + ToString(i)).Value; } //개발언어 var strChkPlan_ = "chkPlan_"; var strChkRslt_ = "chkRslt_"; for(var i=1 ; i-1 < chkCnt ; i++){ eval(strChkRslt_ + ToString(i)).Value = eval(strChkPlan_ + ToString(i)).Value; //chkPlan_OnClick(eval(strChkRslt_ + ToString(i)) // ,eval(strChkRslt_ + ToString(i)).Value); } /* //난이도 cmbRsltApp1.Value = cmbPlanApp1.Value; //신규여부 cmbRsltApp2.Value = cmbPlanApp2.Value; //대외 인터페이스 연관 cmbRsltApp3.Value = cmbPlanApp3.Value; //고유식별정보작업유무 cmbRsltApp4.Value = cmbPlanApp4.Value; //PC저장고유식별번호포함파일삭제확인 cmbRsltApp5.Value = cmbPlanApp5.Value; //변경CI edtRslt_1.Text = edtPlan_1.Text; edtRslt_2.Text = edtPlan_2.Text; edtRslt_3.Text = edtPlan_3.Text; edtRslt_4.Text = edtPlan_4.Text; edtRsltSum.Text = edtPlanSum.Text; //개발언어 chkPlan_1.Value = chkRslt_1.Value; chkPlan_2.Value = chkRslt_2.Value; chkPlan_3.Value = chkRslt_3.Value; chkPlan_4.Value = chkRslt_4.Value; chkPlan_5.Value = chkRslt_5.Value; chkPlan_6.Value = chkRslt_6.Value; chkPlan_7.Value = chkRslt_7.Value; chkPlan_8.Value = chkRslt_8.Value; */ // component event 실행 //=================================================== cmbPlanApp1_OnChanged(Object("cmbRsltApp1"),Object("cmbRsltApp1").Value,Object("cmbRsltApp1").Text,'',''); cmbPlanApp2_OnChanged(Object("cmbRsltApp2"),Object("cmbRsltApp2").Value,Object("cmbRsltApp2").Text,'',''); edtPlan_OnCharChanged(Object("edtRslt_1"),'',Object("edtRslt_1").Text); edtPlan_OnCharChanged(Object("edtRslt_2"),'',Object("edtRslt_2").Text); edtPlan_OnCharChanged(Object("edtRslt_3"),'',Object("edtRslt_3").Text); edtPlan_OnCharChanged(Object("edtRslt_4"),'',Object("edtRslt_4").Text); cmbPlanApp3_OnChanged(Object("cmbRsltApp3"),Object("cmbRsltApp3").Value,Object("cmbRsltApp3").Text,'',''); cmbPlanApp4_OnChanged(Object("cmbRsltApp4"),Object("cmbRsltApp4").Value,Object("cmbRsltApp4").Text,'',''); // 확인결과 cmbPlanApp5_OnChanged()는 cmbPlanApp4_OnChanged() 함수 내부에서 실행시켜주는 스크립트가 존재 //cmbPlanApp5_OnChanged(Object("cmbRsltApp5"),Object("cmbRsltApp5").Value,Object("cmbRsltApp5").Text,'',''); //chkPlan_OnClick(Object("chkRslt_1"),Object("chkRslt_1").Value); for(var i=1 ; i-1 < chkCnt ; i++){ chkPlan_OnClick(eval(strChkRslt_ + ToString(i)) ,eval(strChkRslt_ + ToString(i)).Value); } /* var wObj = AllWindows(); for (var i = 0 ; i < wObj.count; i++ ) { trace("33333 = " + wObj[i].id); } */ //===================================================
script(eval 적용 후)
function btnSameAsPlan_OnClick(obj) { // 결과인 경우 if(planYn == "N"){ //계획/실적공수는 copy 안함 //계획/실적공수 //edtRsltMh.Text = edtPlanMh.Text; //edtRsltMh.Value = edtPlanMh.Value; //난이도 //신규여부 //대외 인터페이스 연관 //고유식별정보작업유무 //PC저장고유식별번호포함파일삭제확인 var strCmbPlanApp = "cmbPlanApp"; var strCmbRsltApp = "cmbRsltApp"; for(var i=1 ; i-1 < 5 ; i++){ eval(strCmbRsltApp + ToString(i)).Value = eval(strCmbPlanApp + ToString(i)).Value; // component event 실행 if(i==1){ cmbPlanApp1_OnChanged(eval(strCmbRsltApp+ToString(i)),eval(strCmbRsltApp+ToString(i)).Value,eval(strCmbRsltApp+ToString(i)).Text,'',''); } if(i==2){ cmbPlanApp2_OnChanged(eval(strCmbRsltApp+ToString(i)),eval(strCmbRsltApp+ToString(i)).Value,eval(strCmbRsltApp+ToString(i)).Text,'',''); } if(i==3){ cmbPlanApp3_OnChanged(eval(strCmbRsltApp+ToString(i)),eval(strCmbRsltApp+ToString(i)).Value,eval(strCmbRsltApp+ToString(i)).Text,'',''); } if(i==4){ cmbPlanApp4_OnChanged(eval(strCmbRsltApp+ToString(i)),eval(strCmbRsltApp+ToString(i)).Value,eval(strCmbRsltApp+ToString(i)).Text,'',''); } // 확인결과 cmbPlanApp5_OnChanged()는 cmbPlanApp4_OnChanged() 함수 내부에서 실행시켜주는 스크립트가 존재 //cmbPlanApp5_OnChanged(Object("cmbRsltApp5"),Object("cmbRsltApp5").Value,Object("cmbRsltApp5").Text,'',''); } //변경CI (합계 포함) var strEdtPlan_ = "edtPlan_"; var strEdtRslt_ = "edtRslt_"; for(var i=1 ; i-1 < 4 ; i++){ eval(strEdtRslt_ + ToString(i)).Value = eval(strEdtPlan_ + ToString(i)).Value; // component event 실행 edtPlan_OnCharChanged(eval(strEdtRslt_+ToString(i)),'',eval(strEdtRslt_+ToString(i)).Text); } //개발언어 var strChkPlan_ = "chkPlan_"; var strChkRslt_ = "chkRslt_"; for(var i=1 ; i-1 < chkCnt ; i++){ eval(strChkRslt_ + ToString(i)).Value = eval(strChkPlan_ + ToString(i)).Value; // component event 실행 chkPlan_OnClick(eval(strChkRslt_ + ToString(i)),eval(strChkRslt_ + ToString(i)).Value); } } }
*** 추가
- onChanged event의 경우 event function 부분은 eval로 구현이 안됩니다. 따라서 eval 함수를 사용하려면
전역에 선언된 함수를 변형하거나(이 경우 해당 함수를 호출하는 모든 스크립트의 수정이 동반되어야함)
혹은 onChanged에 event에 준하는 새로운 함수를 생성자부터 입력해줘야하는데(new function : 이 경우 Function 함수와 동일), 둘 다 너무 번거로워서 가장 쉬운방법으로 진행하였습니다.
- 사용된 프레임워크는 tobesoft사의 miplatform이므로 보편적인 javascript와 차이가 있을 수 있으니 유의해주시기 바랍니다.
=====================================================
참고 :
eval유효범위 오류에 대한 글
https://webclub.tistory.com/512
eval 상세분석 글(영문)
http://perfectionkills.com/global-eval-what-are-the-options/
eval과 Function 간단 비교 및 정리 글 - 요약 : eval과 Function 모두 동적으로 함수를 생성하는 기능이 있지만 Function은 내부에서 선언한 변수를 해당 스코프의 지역변수로써 관리한다(eval에 비해 안전하다)
'JavaScript 공부' 카테고리의 다른 글
jQuery : 모바일/PC 환경에서 터치/마우스 스크롤 + 무한스크롤 기능 (0) | 2019.08.09 |
---|---|
jQuery : 모바일/PC 환경에서 터치/마우스 스크롤 기능 (0) | 2019.08.08 |
무한 스크롤(Infinity Scrolling) + 좌우로 화면을 밀어서 페이지이동(Swipe, Flick) (0) | 2019.07.29 |
크롬 개발자 도구로 JavaScript, HTML 디버깅 (0) | 2019.07.23 |
Double submit 방지 - 뒤로가기, F5새로고침 시 이전 페이지의 로직 중복수행 방지 (0) | 2017.07.30 |
[java/jsp] Html Tag(태그) 제거하는 정규식 (0) | 2017.05.22 |
css에서 클래스(class)와 아이디(id) (0) | 2017.05.22 |
JavaScript에서 id와 name의 차이 (0) | 2017.05.22 |