함수(function)
자바스크립트에서 함수는 객체이다.
그 중에서도 함수는 특히나, 1급 객체(first-class Object)이다.
여러 블로그나 자료들을 보면 함수는 객체이며, 1급 객체이다 라는 말이 많이 등장한다.
그렇다면 1급 객체란 무엇일까?
1급 객체를 알아보기전에 먼저 1급 시민(first-class citizen)을 알아야한다.
1급 시민의 개념은 영국의 컴퓨터 과학자 크리스토퍼 스트레이치에 의해 1960년대 처음 소개 되었으며,
조건은 다음과 같다.
1) 변수에 담을 수 있다.
2) 인자로 전달할 수 있다.
3) 반환값으로 돌려 받을 수 있다.
4) 할당된 이름과 상관없이 고유한 구별이 가능하다
5) 동적으로 프로퍼티 할당이 가능하다.
예를 들어, 대부분의 프로그래밍 언어에서 숫자(Number) 값은 변수에 담을 수 있으며,
인자로 전달이 가능하고, 반환값으로 돌려 받을 수 있으므로 1급 시민의 자격을 가진다.
그러나 C 등의 언어에서는 배열이나 문자열이 값이 아닌 포인터를 전달하므로 1급 시민의 자격을 얻지 못한다.
이와 같은 맥락에서 1급 객체란,
객체로써 1급 시민의 조건에 모두 해당되는 것을 뜻한다.
이를 기반으로 볼 때, 자바스크립트에서는 함수가 위의 조건을 모두 충족하기 때문에
1급 객체, 또는 1급 함수라고 불린다.
함수 선언식(declaration)과 표현식(expression)
1 2 3 4 | // 함수선언식(function declaration) function example() { /* 실행코드 */ } | cs |
자바스크립트에서 함수를 선언할 때는 일반적으로 다음과 같이 표현한다.
이와 같은 방식을 함수 선언식(function declaration)이라고 하는데,
전통적인 프로그래밍에서 선언하던 함수 모양과 비슷하다.
함수 선언식으로 함수를 선언하면, 인터프리터가 스크립트를 로딩할 때 초기화 되며,
이를 변수 객체(VO - variable object)에 저장한다.
따라서 위치와 상관없이 어느 곳에서나 호출이 가능하게 된다.
1 2 3 4 5 6 7 8 9 | // 기명 함수표현식(named function expression) var func = function func() { /* 실행코드 */ }; // 익명 함수표현식(anonymous function expression) var func = function() { /* 실행코드 */ }; | cs |
일반적이 함수 선언식과 다르게, 1급 객체가 변수로써 저장이 가능하다는 점에 착안하여
위와 같은 코드로 함수를 만드는것이 가능한데,
이를 함수 표현식(function expression)이라고 한다.
함수 선언식은 인터프리터가 스크립트를 로딩시 함수를 변수 객체에 저장하는데 반해
표현식은 런타임시에 해석되고 실행되는 것이 큰 차이점이라고 할 수있다.
따라서 함수 선언식으로 사용할 경우 사용하기 쉽지만 대규모 애플리케이션을 만들 때
인터프리터가 너무 많은 코드를 변수 객체에 저장하므로 애플리케이션의 응답속도가 떨어지기 때문에 주의해야한다.
즉시 실행 함수(immediately-invoked function)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // 일반적인 함수호출(function declaration) var hello = function() { console.log('Hello world'); }; hello(); // 기명 즉시실행함수(named immediately-invoked function expression) (function company() { console.log('Hello world'); }()); // 익명 즉시실행함수(immediately-invoked function expression) (function() { console.log('Hello world'); }()); // 익명 즉시실행함수(immediately-invoked function expression) (function() { console.log('Hello world'); })(); | cs |
자바스크립트에서 끊임없이 나온 문제점은 전역 변수로 인한 오류이다.
전역 변수를 사용할 경우
1) 어디서나 전역 변수에 접근이 가능하다
2) 외부에 공유되면 안되는 메소드가 노출된다.
3) 동일한 메소드나 변수 이름으로 원치 않은 결과가 나온다.
이러한 문제점을 해결하기 위해, 코드 작성 과정에서 여러가지 패턴들이 등장 하게 되었고,
함수 선언 시에는 즉시 실행 함수(immediately-invoked function)를 사용하게 되었다.
즉시 실행 함수는 함수 자체를 단순히 괄호 안에 집어넣고 실행한 것이다
그러나 함수를 정의하고, 변수에 함수를 저장하고 실행하는 과정이 있는 함수 선언식과는 다르게
이와 같은 과정을 거치지 않고 바로 실행된다는 특징이 있다.
위의 코드들은 기존에 사용하던 함수 선언식과 즉시 실행 함수를 만드는 3가지 방법을 나타낸 것이다.
이 중에서 더글라스 크락포드는 첫번째 익명 즉시 실행 함수를 권장한다.
1 2 3 4 5 6 7 8 | var app = (function() { var hidenVal = 'hiden'; return { val : hiden }; }()); console.log(app.val); | cs |
이러한 즉시 실행 함수를 사용하게 되면 위와 같이 private 변수를 흉내낼 수 있다.
사실 위와 같은 방법은 클로저를 사용한 것으로
이런 코드 방식을 패턴화 시켜 모듈 패턴이라고 부른다.
자바스크립트는 public, private에 대한 구체적인 문법은 없지만
언어에서 제공되는 기본적인 기능을 활용해서 비공개 변수/메소드를 만들수 있다.
따라서 즉시 실행함수는 글로벌 네임스페이스에 변수를 추가하지 않아도 되기 때문에
코드 충돌없이 구현할 수 있어, 플러그인이나 라이브러리등을 만들때 많이 사용된다.
참고 : http://www.nextree.co.kr/p4150/
http://bestalign.github.io/2015/10/18/first-class-object/
https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4
'개발' 카테고리의 다른 글
[파이썬&루비] 문자와 데이터 타입 (0) | 2017.05.28 |
---|---|
[파이썬&루비] 수와 계산 (0) | 2017.05.28 |
[Javascript] 자바스크립트의 실행 문맥(Context) (0) | 2017.05.24 |
[Javascript] Scope와 변수 (0) | 2017.05.24 |
[Javascript] 객체(Object) (0) | 2017.05.23 |
댓글