new Function 문법

양주영·2021년 9월 5일
0

javascript

목록 보기
20/42

함수 표현식과 함수 선언문 이외에 함수를 만들 수 있는 방법이 하나 더 있다.

문법


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

let func = new Function ([arg1, arg2, ...argN], functionBody);

새로 만들어지는 함수는 인수 arg1...argN과 함수 본문 functionBody로 구성된다.
인수 두 개가 있는 함수를 예로 들어보자.

let sum = new Function('a', 'b', 'return a + b');

alert( sum(1, 2) ); // 3

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

let sayHi = new Function('alert("Hello")');

sayHi(); // Hello

기존에 사용하던 방법과 new Function을 사용해 함수를 만드는 방법의 가장 큰 차이는 런타임에 받은 문자열을 사용해 함수를 만들 수 있다는 점이다.
개발자가 직접 스크립트를 작성해야만 함수를 만들 수 있었던 함수 표현식과 함수 선언문과 달리,
new Function이라는 문법을 사용하면 어떤 문자열도 함수로 바꿀 수 있다. 서버에서 전달받은 문자열을 이용해 새로운 함수를 만들고 이를 실행하는 것도 가능하다.

let str = ... 서버에서 동적으로 전달받은 문자열(코드 형태) ...

let func = new Function(str);
func();

💡 언제 사용할까?

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



클로저


함수는 특별한 프로퍼티 [[Environment]]에 저장된 정보를 이용해 자기 자신이 태어난 곳을 기억한다. 
그런데 new Function을 이용해 함수를 만들면 함수의 [[Environment]] 프로퍼티가 현재 렉시컬 환경이 아닌 전역 렉시컬 환경을 참조하게 된다.
따라서 new Function을 이용해 만든 함수는 외부 변수에 접근할 수 없고, 오직 전역 변수에만 접근할 수 있다.

function getFunc() {
  let value = "test";

  let func = new Function('alert(value)');

  return func;
}

getFunc()(); // ReferenceError: value is not defined

new Function은 실무에서 아주 유용하게 쓰인다.
new Function으로 만든 새로운 함수 내부에서 외부 변수에 접근하려 할 때, 기존 함수 선언 방식으로 작성한 함수와 동일한 동작이 보장되어야 한다.
그런데 스크립트가 프로덕션 서버에 반영되기 전, 압축기(minifier) 에 의해 압축될 때 문제가 발생한다. 압축기는 스크립트에서 주석이나 여분의 공백 등을 없애 코드 크기를 줄여주는 특수한 프로그램인데 압축기가 지역 변수 이름을 짧게 바꾸면서 문제가 발생한다.

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

이런 실수로부터 예방하기 위해 new Function에는 특별한 기능이 있다.
함수 내부에서 외부 변수에 접근하는 것은 아키텍처 관점에서도 좋지 않고 에러에 취약하다.
new Function으로 만든 함수에 무언갈 넘겨주고 싶다면 인수를 사용하자.



📝 정리


  • 문법 :
let func = new Function ([arg1, arg2, ...argN], functionBody);
  • 인수를 한꺼번에 모아(쉼표로 구분) 전달할 수도 있다.

    아래 세 선언 방식은 동일하게 작동한다.

new Function('a', 'b', 'return a + b'); // 기본 문법
new Function('a,b', 'return a + b'); // 쉼표로 구분
new Function('a , b', 'return a + b'); // 쉼표와 공백으로 구분
  • new Function을 이용해 만든 함수의 [[Environment]]는 외부 렉시컬 환경이 아닌 전역 렉시컬 환경을 참조하므로 외부 변수를 사용할 수 없다. 단점 같아 보이는 특징이긴 하지만 에러를 예방해 준다는 관점에선 장점이 되기도 한다. 구조상으로 매개변수를 사용해 값을 받아 압축기에 의한 에러도 방지할 수 있다.



참조 : https://ko.javascript.info/new-function

profile
뚜벅뚜벅

0개의 댓글