JavaScript - new Function 문법

Leejunyoung·2022년 8월 30일
0

JavaScript

목록 보기
48/49

new Function 문법

함수 표현식과 함수 선언문 이외에 함수를 만들 수도 있는 방법이 하나 더 있다. 잘 사용하는 방법은 아니지만, 이 방법 외에는 대안이 없을 때 사용한다.

문법

new Function 문법을 사용하면 함수를 만들 수 있다.

새로 만들어지는 함수는 인수 arg1...argN과 함수 본문 functionBody로 구성된다.
인수 두 개가 있는 함수를 직접 만들어 보면서 new Function 문법에 대해 이해해보자.

인수가 없고 함수 본문만 있는 함수를 만들어보자.

기존에 사용하던 방법과 new function을 사용해 함수를 만드는 방법의 가장 큰 차이는 런타임에 받은 문자열을 사용해 함수를 만들 수 있다는 점이다.

함수 표현식과 함수 선언문은 개발자가 직접 스크립트를 작성해야만 함수를 만들 수 있었다.

그러나 new Function이라는 문법을 사용하면 어떤 문자열도 함수로 바꿀 수 있다. 서버에서 전달 받은 문자열을 이용해 새로운 함수를 만들고 이를 실행하는 것도 가능하다.

서버에서 코드를 받거나 템플릿을 사용해 함수를 동적으로 컴파일해야 하는 경우, 복잡한 웹 애플리케이션을 구현할 때와 같이 아주 특별한 경우에 new Function을 사용할 수 있다.


클로저

함수는 특별한 프로퍼티 [[Environment]] 에 저장된 정보를 이용해 자기 자신이 태어난 곳을 기억한다. [[Environment]]는 함수가 만들어진 렉시컬 환경을 참조한다.

그런데 new Function을 이용해 함수를 만들면 함수의 [[Environment]] 프로퍼티가 현재 렉시컬 환경이 아닌 전역 렉시컬 환경을 참조하게 된다.

따라서 new Function을 이용해 만든 함수는 외부 변수에 접근할 수 없고, 오직 전역 변수에만 접근할 수 있다.

일반적인 방법을 사용해 함수를 정의한 예시와 비교해보자.

지금 당장은 new Function이 제공하는 특수한 기능이 익숙하지 않을 수 있는데, 실무에선 이 기능이 아주 유용하게 쓰인.

문자열을 사용해서 함수를 만들어야 한다고 가정해보자. 스크립트를 작성하는 시점엔 어떻게 함수를 짤지 알 수 없어서 기존의 함수 선언 방법은 사용하지 못하는데, 스크립트 실행 시점 즈음엔 함수를 어떻게 짜야 할 지 아이디어가 떠오를 수 있을 것이다. 이때, 서버를 비롯한 외부 출처를 통해 코드를 받아올 수 있다.

그런데 이렇게 만들어진 새 함수는 기존 스크립트와 문제없이 상호작용할 수 있어야한다.

new Function으로 만든 새로운 함수 내부에서 외부 변수에 접근하려 할 때, 기존 함수 선언 방식으로 작성한 함수와 동일한 동작이 보장되어한다.

그런데 스크립트가 프로덕션 서버에 반영되기 전, 압축기(minifier) 에 의해 압축될 때 문제가 발생한다. 압축기는 스크립트에서 주석이나 여분의 공백 등을 없애 코드 크기를 줄여주는 특수한 프로그램인데 압축기가 지역 변수 이름을 짧게 바꾸면서 문제가 발생한다.

구체적으로 어떤 부분이 문제가 되는지 예시를 통해 알아보자. 함수 내부에 let userName라는 변수가 있으면 이 지역변수는 압축기에 의해 let a 등(짧은 이름)으로 대체되는데, 이때 userName 모두가 a로 교체된다. userName은 지역변수이고, 함수 외부에선 함수 내부에 있는 변수에 접근할 수 없기 때문에 이렇게 해도 전혀 문제가 없다. 압축기는 단순히 변수를 찾아서 바꾸지 않고 코드 구조를 분석해 기존에 작성한 코드의 기능을 망가뜨리지 않으면서 영리하게 제 역할을 수행한다.

이런 동작 방식 때문에 new Function 문법으로 만든 함수 내부에서 외부 변수에 접근하려고 하면 userName은 이미 이름이 변경되었기 때문에 찾을 수 없게 된다.

압축기가 동작한 이후엔, new Function으로 만든 함수 내부에서 외부 렉시컬 환경에 접근하려고 할 때 문제가 발생할 수 있다.

이런 실수로부터 예방하기 위해 new Function에는 특별한 기능이 있다.

함수 내부에서 외부 변수에 접근하는 것은 아키텍처 관점에서도 좋지 않고 에러에 취약하다.

new Function으로 만든 함수에 무언갈 넘겨주고 싶다면 인수를 사용하자.

profile
안녕하세요

0개의 댓글