관리 메뉴

공부한것들을 정리하는 블로그 입니다.

javascript eval 함수 본문

JavaScript 공부

javascript eval 함수

호 두 2019. 6. 7. 16:39
반응형

 

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() 사용과 문제점 : #eval() is evil

eval() is evil 코드에서 eval() 을 발견하면 'eval() 은 사악하다(eval() is evil)'라는 주문을 기억하라! 이 함수는 임의의 문자열을 받아 자바스크립트 코드로 실행합니다. 만약 문제의 코드를 사전에 알 수 있..

webclub.tistory.com

 

eval 상세분석 글(영문)

http://perfectionkills.com/global-eval-what-are-the-options/

 

Global eval. What are the options? — Perfection Kills

← back 4073 words 15 December 2010 Global eval. What are the options? David Flanagan recently wrote about global eval() in Javascript, proposing a simple one-liner like this: var geval = this.execScript || eval; Even though it looked beautifully simple, it

perfectionkills.com

 

eval과 Function 간단 비교 및 정리 글 - 요약 : eval과 Function 모두 동적으로 함수를 생성하는 기능이 있지만 Function은 내부에서 선언한 변수를 해당 스코프의 지역변수로써 관리한다(eval에 비해 안전하다)

http://blog.daum.net/sansamgu/33

반응형
Comments