자바스크립트에서 eval()은 사악한(evil) 함수이다.
동적인 프로퍼티에 접근할 때에는 대괄호 표기법이 더 간단하고 좋다.
//안티 패턴 var obj = {name:"javascript"}; var property = "name"; alert(eval("obj."+property))
// 권장 패턴 var obj = {name:"javascript"}; var property = "name"; alert(obj[property])
setInterval(), setTimeout(), Function() 인자로 문자열을 넘기는 것도 eval()과 비슷하다.
반드시 eval()을 사용해야 한다면
- new Function()으로 감싸서 사용하자.
Function() 생성자로 감싸게되면 유효영역이 새로 만들어져 var 선언 변수들이 전역에 선언되는 경우를 막을 수 있다. - eval() 호출을 즉시실행 함수로 감싸서 실행되도록 하자.
console.log(typeof un); // undefined console.log(typeof deux); // undefined console.log(typeof trois); // undefined var jsstring = "var un = 1; console.log(un);"; eval(jsstring); // "1" jsstring = "var deux = 2; console.log(deux);"; new Function(jsstring)(); // "2" // 생성자로 생성한 함수를 바로 호출한다. // 유효범위가 새로 생기므로 deux는 로컬변수가 된다. jsstring = "var trois = 3; console.log(trois);"; (function() { eval(jsstring); }()); // "3" // eval()을 함수로 감싸고 그 함수를 즉시 호출한다. trois 또한 함수의 로컬변수가 된다. console.log(typeof un); // "1" console.log(typeof deux); // "undefined" console.log(typeof trois); // "undefined"
eval()과 Function()의 또다른 차이
eval()은 자신의 유효범위 다음으로 자신을 감싸는 유효범위를 바라보고 있다.
하지만 Function()은 자신의 유효범위 다음으로 전역 유효범위를 바라보고 있다.
따라서 eval()은 유효범위 체인에 간섭을 일으킬 수 있다.
(function () { var local = 1; eval("local = 3; console.log(local);"); // 3이 출력된다. console.log(local); // 3이 출력된다. 감싸고있는 함수의 local 변수의 값을 바꿔버린다. }()) (function () { var local = 1; Function("console.log(typeof local);")(); // undefined가 출력된다. // Function 객체의 상위 유효범위는 전역. // 전역에 local 변수가 없으므로 undefined. }())
'WEB > javascript' 카테고리의 다른 글
객체 생성자의 함정 (0) | 2012.07.22 |
---|---|
자바스크립트 리터럴 표기법 (0) | 2012.07.22 |
호이스팅(hoisting): 분산된 var 선언의 문제점 (0) | 2012.07.12 |
자바스크립트 전역변수 (0) | 2012.07.10 |
strict mode (0) | 2012.07.10 |