script&JQuery - eval()

eval()

문자열을 코드로 인식하게 하는 함수

eval( '2+2' )

는 문자열 2+2가 아니라 계산한 결과 4

eval 함수의 파라메터로 입력된 String은 JavaScript 파서에 의해 구문 분석되고 실행 된다

eval 함수에 전달된 코드는 eval 함수가 호출되는 것과 같은 상황에서 실행되며 실행된 코드에 리턴값이 있는경우 해당 값을 리턴 해준다

eval(string)은 문자열로 넘어온 자바스크립트 구문을 실행하는데,
호출하는 위치와 방식에 따라 eval의 실행 컨텍스트와 범위(scope)가 달라진다.
기본적으로, eval 은 실행 시점의 함수 범위(scope)에서 실행되며,
eval()의 실행 컨텍스트(this) 또한 실행 시점의 함수의 것과 동일하다.

 var a = {

    b: function () {

      var foo = 'foo';

      return eval('foo'); // (A)

    },

    c: function () {

      return eval('this'); // (B)

    }

  };



  a.b(); //--> 'foo'

  a === a.c(); //--> true
  

(A)의 eval은 a.b() 메서드 내에서 호출되며 b()와 동일한 범위를 갖기 때문에,
지역변수인 foo에 접근할 수 있다.
또한, (B)에서와 같이 this 또한 c()의 실행 컨텍스트인 a 객체를 가리킨다.

단, eval을 직접 호출하지 않는 경우,
eval은 전역 범위(global scope)에서 실행된다.

'직접 호출(direct call)'하지 않는다는 것은, eval의 참조를 이용해 호출하는 것을 의미하며,
'indirect call'이라 한다. (우리 말론 '간접 호출'이라고 해야할까...?)

var foo = 'global_foo';



  function directEval() {

    var foo = 'local_foo';

    return eval('foo');

  }



  function indirectEval() {

    var foo = 'local_foo';

    var f = eval; // 직접 eval을 호출하지 않고 eval의 참조를 호출한다.

    return f('foo');

  }



  directEval(); //--> 'local_foo'

  indirectEval(); //--> 'global_foo'

최근의 자바스크립트 컴파일러는 성능 향상을 위해 미리 코드를 컴파일하는데,
eval()과 같이 동적으로 실행 범위가 결정되는 코드는 미리 컴파일할 수 없다.

그렇기 때문에, 함수 내에서 실행되는 eval()이 반드시 함수의 실행 범위를 가져야 하는 것이 아니라면,
eval의 참조를 이용해(indirect call) 명시적으로 전역 범위에서 실행되도록 하는 것이 좋다.

참고 : https://programmingsummaries.tistory.com/179
참고 : https://ohgyun.com/395
참고 : eval과 Function의 차이점에 대해 설명함. http://blog.daum.net/sansamgu/33

scope
Scope를 우리말로 번역하면 ‘범위’라는 뜻을 가지고 있습니다. 즉, 스코프(Scope)란 ‘변수에 접근할 수 있는 범위’라고 할 수 있는데요.
자바스크립트에선 스코프는 2가지 타입이 있습니다. 바로 global(전역)과 local(지역) 인데요.

eval은 실행되는 문자열의 외부 유효범위에 접근, 수정이 가능

Funcition 과 eval 둘다 동적 함수를 생성하는 기능은 동일하나 Function은 내부에서 var로 생성된 변수가 자동으로 전역변수가 되어버리는 현상을 만들지 않고 , 오로지 전역 스코프만 접근할수 있기 때문에 eval에 비해 안전하다고 할수 있다 꼭 동적으로 코드를 수행해야 할경우 Frunction 생성자를 사용하는것이 바람직하다

좋은 웹페이지 즐겨찾기