eval()
함수는 전달된 문자열을 JavaScript 코드로 해석하고 실행한다.
eval(code)
var x = 5;
var code = "console.log(x + 10);"; // 실행할 코드를 문자열로 정의
eval(code); // 결과: 15
이처럼 eval 함수는 유연하고 강력한 도구다. 때문에 제대로 이해해 두는 것이 좋다.
eval의 이상한 동작을 확인하기 위한 가장 쉬운 방법은 스코프를 침범하게 만드는 것이다.
eval 은 자신의 인자를 자바스크립트 프로그램처럼 해석하지만, 이 프로그램은 호출자의 지역 스코프
안에서 실행된다. 임베디드된 프로그램의 전역변수는 호출한 프로그램의 지역변수로 생성된다.
function test(x){
eval("var y = x;");
return y;
}
test("hello"). //hello
여기서 var 선언문은 오직 eval 함수가 호출될 때에만 실행된다. eval을 조건적인 문맥에 위치시키면 해당 조건문이 실행될 때에만 그 변수를 스코프 내로 가져오게 된다.
var y = "global"
function test(x){
if(x){
eval("var y = 'loacl';"); //동적 바인딩
}
return y;
}
test(true); // "local"
test(false); // "global"
스코프를 프로그램의 동적인 동작에 의해 결정하는 방법은 대부분의 경우 좋지 않다.
소스코드를 지역적으로 선언하지 않고 다음과 같이 eval에 전달하면 특히 더 교묘해진다.
var y = "global"
function test(src){
eval(src)
return y;
}
test("var y = 'local';"); //local
test("var z = 'local';"); //global
이 코드는 불안정하고 안전하지 않다. 외부의 호출자가 test 함수 내부의 스코프를 변경할 수 있기 때문이다. 또한 ES5 스트릭트 모드의 호환성에 적합하지 않다.
eval이 외부 스코프에 영향일 주지 않도록 하는 방법은 감싸진 스코프 안에서 실행되도록 하는것이다.
var y = "global"
function test(src){
(function(){eval(src)})();
return y;
}
test("var y = 'local';"); //global
test("var z = 'local';"); //global