[JavaScript] 내장 함수 eval

eval의 기본 사용법

eval은 전달된 문자열을 실행한 후, 마지막 표현식의 결과를 반환합니다.

let result = eval('2 + 3 * 4');
console.log(result); // 14

위의 예에서 eval() 함수는 문자열 '2 + 3 * 4'를 JavaScript 코드로 평가하고 결과를 result 변수에 할당합니다.

여러 줄의 코드도 실행할 수 있습니다

let output = eval(`
  let x = 10;
  let y = 20;
  x + y;
`);
console.log(output); // 출력: 30

문자열 내부에 포함된 코드가 현재의 렉시컬 환경에서 실행되므로, 외부 변수에 접근하거나 수정할 수 있습니다.

eval의 렉시컬 환경

eval은 기본적으로 현재 실행 중인 환경(스코프)에서 코드를 실행합니다.

let greeting = "Hello";

function showGreeting() {
  // 현재 스코프의 greeting 변수에 접근합니다.
  eval('console.log(greeting + ", world!");');
}

showGreeting(); // "Hello, world!" 출력

위 예제처럼 eval 내부의 코드는 호출 위치의 스코프에 접근할 수 있기 때문에, 외부 변수를 읽거나 변경할 수 있습니다:

let count = 1;
eval('count = count + 1');
console.log(count); // 2

하지만 엄격 모드에서는 eval이 별도의 렉시컬 환경을 생성하기 때문에, eval 내부에서 선언된 변수나 함수는 외부에서 접근할 수 없습니다.

"use strict";
eval('let secret = "hidden";');
console.log(typeof secret); // "undefined"

eval 사용의 단점

보안 문제

외부에서 받은 데이터를 그대로 eval에 전달하면, 악의적인 코드가 실행될 위험이 있습니다.

유지보수 및 디버깅

문자열로 작성된 코드는 정적 분석이나 IDE의 코드 완성 기능이 제대로 작동하지 않아, 유지보수가 어렵습니다.

eval 대체 방법

전역 스코프에서 코드 실행하기: window.eval

만약 반드시 전역 스코프에서 코드를 실행하고 싶다면, window.eval을 사용하면 됩니다. 이는 eval이 현재 스코프 대신 전역 스코프에서 실행되도록 보장합니다.

let localVar = "Local";
{
  let localVar = "Block";
  window.eval('console.log(typeof localVar, localVar);');
  // 전역 범위의 localVar가 출력됩니다. (예: "string", "Local")
}

new Function 생성자

new Function 생성자는 문자열을 받아 새로운 함수를 만들어 전역 스코프에서 실행합니다. 이 방식은 eval과 달리, 자신만의 독립적인 스코프를 갖기 때문에 외부 변수에 영향을 주지 않습니다.

const sum = new Function('a', 'b', 'return a + b;');
console.log(sum(5, 7)); // 12

// eval 대신 사용하면, 새로운 함수를 정의하는 것과 동일합니다.