JavaScript

[JavaScript] #22 - eval() 함수

yoonddo 2023. 1. 29. 19:34

eval()은 전역 객체의 함수 속성이다. 인자는 문자열이며 인자가 표현식을 나타낸다면 eval()은 표현식을

평가한다. 인자가 하나 이상의 JavaScript 명령문을 나타낸다면 모두 실행한다. 연산식을 계산하기 위해

eval()을 호출하지 마라. 자바스크립트는 연산식을 알아서 계산하기 때문이다.


일반적으로는 다음 예제처럼 함수의 매개변수로 문자 값을 사용하면 문자 리터럴로 인식되고 있는

리터럴로 사용된다.

console.log('2 + 2');
// result: '2 + 2'

 

하지만 eval()은 매개변수로 받은 문자 값을 값으로 사용하는 것이 아니라 실행문으로 변환해 실행시키기

때문에 문자를 출력하지 않고 문자의 실행 결과를 반환한다.

console.log(eval('2 + 2'));
// Expected output: 4

console.log(eval(new String('2 + 2')));
// Expected output: 2 + 2

console.log(eval('2 + 2') === eval('4'));
// Expected output: true

console.log(eval('2 + 2') === eval(new String('2 + 2')));
// Expected output: false

또한 정의되어 있는 함수의 실행도 가능하다.

alert()처럼 정의되어 있고 사용이 가능한 함수라면 eval()을 통해 언제나 사용 가능하다.

eval('alert("hello")');

eval()의 인자가 문자열이 아니면 인자를 그대로 반환한다.

eval(new String("2 + 2")); // "2 + 2"를 포함한 String 객체를 반환
eval("2 + 2");             // 4를 반환

 

toString()을 방식으로 제약을 피할 수 있다.

var expression = new String("2 + 2");
eval(expression.toString());            // 4를 반환

기본적으로 eval()은 전역 범위(Scope)에서 동작하기 때문에 함수 뿐만 아니라 변수도 접근이 가능하다.

var count = 1;
var sum = eval('10 + count');

console.log(sum);
// result: 11

 


 

eval을 직접 호출하지 않고 참조를 통해 간접적으로 사용한다면 ECMAScript 5부터는 지역 범위가 아니라

전역 범위에서 동작한다. 예를 들어 eval()로 함수를 선언하면 전역 함수가 되고, 실행되는 코드는 실행되는

위치의 지역 범위에 접근할 수 없다.

예제

function test() {
      var x = 2, y = 4;
      console.log(eval('x + y'));  // 직접 호출, 지역 범위 사용, 결과값은 6
      var geval = eval; // eval을 전역 범위로 호출하는 것과 같음
      console.log(geval('x + y')); // 간접 호출, 전역 범위 사용, `x`가 정의되지 않았으므로 ReferenceError 발생
      (0, eval)('x + y'); // 다른 방식으로 간접 호출
    }

eval을 사용한 코드와 eval이 없는 코드

//eval을 사용하는 나쁜 코드:

function looseJsonParse(obj){
    return eval(obj);
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))
Copy to Clipboard


//eval이 없는 코드:

function looseJsonParse(obj){
    return Function('"use strict";return (' + obj + ')')();
}
console.log(looseJsonParse(
   "{a:(4-1), b:function(){}, c:new Date()}"
))

 

이처럼 eval()은 자유도가 높고 실시간으로 코드를 만들어 사용하기 편하다.

이렇게 살펴본 eval()은 꽤 재미있고 쓰임새가 무궁무진해 보인다. 그런데 eval()은 모던한 자바스크립트

프로그래밍에서는 보기가 어렵다. 그 중 가장 큰 이유는 보안이 취약하다는 점이다. 또한 eval()은 보안

외에도 유지 보수 측면에서 좋지 않은 코드를 생산하도록 유도하는 방법 중 하나이다.

그러므로 실무에서는 절대 사용하지 않아야 한다.

 

 

 

 

 

 

 

 

 

 

 

참고 자료 : https://7942yongdae.tistory.com/149 , https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval

'JavaScript' 카테고리의 다른 글

[JavaScript] #24 - 노드(Node)  (0) 2023.02.02
[JavaScript] #23 - 문자열 함수  (0) 2023.01.30
[JavaScript] #21 - Number 객체  (0) 2023.01.29
[JavaScript] #20 - 아이디 중복 체크하기  (0) 2023.01.26
[JavaScript] #19 - Window 객체  (0) 2023.01.25