본문 바로가기

프로그래밍/javascript(ES)

자바스크립트 eval 함수

안녕하세요! 쨈입니다!

이번 포스트에서는, 제가 자바스크립트를 한창 처음 접했었을 때 정말 구원자 같았던 eval 함수에 대해 이야기를 하려고 합니다.

eval 함수의 사용과 남용에 대해서도 다룰것이니,
천천히 읽어보시면 좋겠습니다.


(그냥 제 블로그 사진)


제가 객체({})의 요소들을 하나하나 document 요소들에게 입력해주어야 했을 때의 일입니다. 특정 이벤트가 발생했을 때 그 객체 안에 있는 특정 요소를 딱 집어서 뭔가를 하는게 문제였는데요.

그때 제가 자바스크립트 외에 다른 언어도 사실상 거의 사용하지 못하는 수준이었기에, 이해도 제대로 되지 않은 상태었기에 그저 다음과 같은 생각만 했습니다.

"코드 자체를 동적으로 만들자"

이었는데.. 알고보니 그런 상상은 상상만이 아니라 실제 함수로 존재한다는 것을 알게 됬습니다. 그게 바로 자바스크립트의 eval 함수 입니다.





eval(string)


eval 함수는 위와 같이 사용할 수 있습니다. 전역 함수로 어디에서나 사용이 가능하며, Node.js 라는 다른 자바스크립트 플랫폼에서도 사용이 가능한 함수입니다.

첫번째 인수로는 string 형식, 즉 문자열을 받습니다.
그리고, 그 문자열을 코드로써 실행한 결과를 return(반환)합니다.

간단한 예제 하나를 보면 쉽게 이해가 될 겁니다.


1
2
3
4
var sum = eval("8+6");
console.log(sum); //14
 
console.log(eval("'java'+'script'")); //javascript
cs


주석처리된 것처럼, 값이 나옵니다. 이처럼 eval 함수 안에는 식도 되고, 각종 실행할수 있는 값들을 넣어서 실제 코드로 실행시키는 것입니다.

eval 함수의 인수로 "alert(222)" 같은 것들을 넣으면, 쓴 대로 222라는 알림창이 뜨고 alert 함수의 반환값인 undefined가 그대로 반환됩니다.


이런면에서 봤을때 eval 함수는 정말로 편리하고 동적이게 보입니다.

사용자에게 입력받은 값을 그대로 실행시켜서 결과가 나오게 할수도 있고 그 외에도 여러 문제를 해결하는데 도움을 주니까요.


하지만 이건 모두 함정 입니다.





eval의 함정


eval은 여러분이 어떤 값을 입력하던 실행시켜줍니다. 이런 점에서 편리하죠! 하지만 이런 점 때문에 프로그램이 버그투성이가 될 수도 있습니다.

eval 함수는 보통 사용자가 입력한 값이 직접 코드에 개입해야 되는 경우에 사용되곤 하는데, 여기서부터 당신의 프로그램은 어떻게 날뛸지 모른다는겁니다.

사용자가 입력한 값을 알맞은 위치에 놓았는데, 만약 사용자가 %나 " 같은 문법에 영향을 주는 문자들을 마구 썼다면 어떻게 될까요?

프로그램의 실행은 멈추게 되고, 대책이 없어집니다. 사용자의 입력으로 이런 현상이 발생했다고 이게 과연 사용자의 잘못일까요? 버그가 있다면 버그가 있다고라도 알려줘야 되는 제작자의 잘못 아닐까요?

이런식의 오류가 발생하면, 사용자는 당연히 "무슨 프로그램이 이래" 라고 불평불만을 하며 꺼버릴 수밖에 없는 상황이 되는 것이죠.

코드에 정말로 개입을 해야 될 때는, 사용자가 입력한 값에 오류가 있을때 다시 바로잡을수 있는 정도는 갖추어져야 사용할 수 있겠죠?



그리고 또 Node.js 같은 "서버" 에서는 사용자가 입력한 값을 인수로 넣어서 eval을 사용하는 행위는 절대 금지입니다.

특히 Node.js는 시스템에 접근이 가능하기에, 컴퓨터까지 제어당할 수 있습니다. 입력받은 값을 제대로 통제할 자신이 없다면 그냥 eval자체를 사용하지 마세요. 괜한 보한 허점을 만들뿐입니다.





쓸데없는 남용



이건 MDN에서도 나온 유형인데,
객체 안의 요소를 참조할때 eval을 사용하는 것입니다.


1
2
3
4
5
var object = {a:1,b:24,c:-8};
 
var id = prompt("ID:");
 
alert(eval("object."+id));
cs


특정 오브젝트에서 사용자에게 ID를 받아 그 ID대로 참조를 해야 된다고 합시다. 이럴 때 위와 같은 코드를 사용하면, object 안에 있는 값을 빼올 수는 있습니다.


하지만 이건 사용자가 정상적 값을 입력했을때 일입니다. 만약 prompt 함수가 물어본 것에 숫자 같은 값을 대답하면 어떻게 될까요?

그렇게 되면 eval 함수에 들어가는 값은 object.24 같이 되버리고, 말도안되는 구문이기때문에 결국 오류가 발생합니다.


이럴때는 대신 object[id] 를 사용하면 됩니다. MDN에도 유사한 글이 있었는데, 혹시라도 이렇게 하는 분들이 계실까봐 올립니다.



eval 이라는 함수는 좋은 면과 나쁜면이 확실하게 있습니다. 그러니 제발, 웬만하면 사용하지 말면 좋겠고, 반드시 사용해야 된다면 꼭 입력받은 값에 대한 검사를 철저히 하길 바랍니다.

그럼, 이만 끝!







-지금 쓰고 있는데 너무 졸려요. zzz..