JS eval(), 함수

sam_il·2022년 7월 13일
0

JavaScript

목록 보기
17/22
post-thumbnail

eval()은 문자로 표현된 JavaScript 코드를 실행하는 함수이며, 전역 객체의 함수 속성이다.

eval(string)


❗ eval은 보안에 취약하므로 eval을 절대 사용하지 말 것!

다른 언어에서도 eval 함수의 취약점으로 인해 사용하지 않는 것이 좋다고 들어왔지만 계산기를 만들면서 이미 알고있던 eval()을 임의로 사용했다. 코드를 리팩토링하며 eval 함수를 정확히 왜 사용하지 않아야 하는지 정리해보았다.

❓ eval()을 사용하지 않아야 하는 이유

  • eval()은 인자로 받은 코드를 caller의 권한으로 수행하는 위험한 함수이다. 악의적인 영향을 미칠 수 있는 문자열을 eval()로 실행한다면, 웹페이지나 확장 프로그램의 권한으로 사용자의 기기에서 악의적인 코드를 수행하게 될 수도 있다. 또한 제 3자가 eval()이 호출된 위치의 스코프를 볼 수 있으며 이를 이용해 비슷한 함수인 Function으로는 실현할 수 없는 공격을 할 수 있다.

  • 최신 JS 엔진에서 여러 코드 구조를 최적화하는 것과 달리 eval()은 JS 인터프리터를 사용해야 하기 때문에 다른 대안들보다 느리다.

  • 마지막으로 최신 JavaScript 인터프리터는 자바스크립트를 기계 코드로 변환한다. 즉, 변수명의 개념이 완전히 없어진다. 그러나 eval을 사용하면 브라우저는 기계 코드에 해당 변수가 있는지 확인하고 값을 대입하기 위해 길고 무거운 변수명 검색을 수행해야 한다. 또한 eval()을 통해 자료형 변경 등 변수에 변화가 일어날 수 있으며 브라우저는 이에 대응하기 위해 기계 코드를 재작성해야 한다.

✅ 이러한 eval을 대체할 수 있는 window.Function이라는 훨씬 좋은 대안이 있다.

❓ window 객체와 BOM

https://www.zerocho.com/category/JavaScript/post/573b321aa54b5e8427432946

※ eval()에 대한 자세한 설명

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval


❗ setInterval() 과 setTimeout() 그리고 Function() 생성자에 문자열을 바로 넘기는 것도 eval()을 사용하는 것과 상당히 비슷하기 때문에, 역시 사용을 자제해야 한다고 한다.



eval()의 대안으로 Function() (new Function()과 동일한 의미, new 생략)을 얘기하는데, 함수의 생성 방식에 대해 정리해보았다.

✅ 자바스크립트에는 함수를 생성하는 방식이 총 3가지이다.

1) 함수 선언식 (function statement)

function func_statement(a,b){
	return a+b
}

호이스팅(hoisting)의 의미는 '끌어올린다'라는 의미로 자바스크립트에서 함수 호이스팅이란 함수를 선언하면 자바스크립트 엔진에 의해 실행 전 코드의 맨 위로 함수 선언 위치가 이동된다. 호이스팅이 일어나기 때문에 함수가 선언되기 전 함수가 호출되어도 에러가 발생하지 않지만, 원래는 함수 선언 전 호출이므로 에러가 발생하는게 맞다.

2) 함수 표현식 (function expression)

var func_expression=function(a,b){
	return a+b
};

함수 표현식에서는 호이스팅이 일어나지 않는다.

3) 함수 생성자 (arg1,arg2,..,argN,본문)

var func_construction=new Function('a','b','return a+b');

일반적인 함수와는 동작하는 방식이 약간 다르다. 함수 표현식과 함수 선언문은 개발자가 직접 스크립트를 작성해야만 함수를 만들수 있지만, new Function이라는 문법을 사용하면 어떤 문자열도 함수로 바꿀 수 있다.

[추가] Function 생성자

📌 참고문서 MDN Function

❗ 참고: Function 생성자를 사용해 함수를 생성하면 일부 JavaScript 엔진 최적화를 적용할 수 없으며, 그 외에도 다른 여러 문제가 발생하므로 권장하지 않는다.

다른 모든 객체처럼, new 연산자를 사용해서 Function 객체를 생성할 수 있다.

new Function (arg1, arg2, ... argN, functionBody)

  • arg1, arg2, ... argN
    함수가 형식 매개변수로 사용할 0개 이상의 이름. 모두 올바른 JavaScript 식별자, 또는 쉼표로 구분한 식별자 목록이어야 한다. ("x", "theValue", "a,b" 등)

  • functionBody
    함수 본문으로 사용할 JavaScript 명령문을 담은 문자열.

Function 생성자를 함수로 호출(new 연산자 없이 호출)하는 것도 동일하게 동작한다.

❓ 즉시 실행 함수(Immediate Function)

function result() {
    //eval 함수 대체 new Function(), new 생략하여 사용
    if (arr != "") {
        const show = (Function('return ' + arr)());
        result.innerHTML = show;
    }
}

eval()을 대체하여 작성한 결과 출력 메서드는 위와 같다. 여기서 (Function()())은 무엇일까? 이처럼 정의된 함수를 즉시 실행 함수(Immediate Function)라고 하며 정식 표준 명칭은 아니라고 한다. 명칭에서 알 수 있듯 코드가 해석되면서 바로 함수가 실행된다. 자바스크립트에서 사용하는 함수 패턴 중 하나라고 생각하면 될 것 같다. 함수 표현식은 함수를 정의하고, 변수에 함수를 저장하고 실행하는 일련의 과정을 거치게 되지만 즉시 실행 함수를 사용하면 이와 같은 과정을 거치지 않고 즉시 실행된다는 특징이 있다. 해당 함수는 주로 scope, closure의 범위를 제한하는 용도로 사용한다.

https://okky.kr/article/171267
https://devyj.tistory.com/9



📌 참고문서

Web Club:티스토리
https://deftkang.tistory.com/19
https://solare.tistory.com/131
함수 생성 3가지 방식
https://chanyeong.com/blog/post/9

profile
🍀

0개의 댓글