함수 표현식

2014. 10. 23. 09:55 나홀로스터디/JS For Web Dev


7장 함수 표현식

이 포스팅은 "프론트엔드 개발자를 위한 자바스크립트(2013 인사이트, 한선용 옮김)"에서 발췌 요약한 것입니다.
 
함수 표현식의 특징
함수와 재귀
클로저를 이용한 고유 변수


함수를 정의하는 방법은 함수 선언함수 표현식 두 가지다.

첫 번째 방법인 함수 선언은 function 키워드에 함수 이름을 쓰는 형태로 파이어폭스, 사파리, 크롬, 오페라는 모든 함수에 프로퍼티인 name을 지원하므로 이 값은 function 키워드 다음에 쓴 함수의 이름과 항상 일치한다.
function functionName(arg0, arg1, arg2){
  // 함수 본문
}
alert(functionName.name);  // "functionName"
함수 선언에서 가장 뚜렷한 특징은 '함수 선언 끌어올림(함수 선언부를 다른 코드보다 먼저 읽고 실행한다)'이다.


함수를 정의하는 두 번째 방법은 함수 표현식이다.
var functionName = function(arg0. arg1. arg2){
  // function body
}
함수를 생성하고 이를 functionName 이란 변수에 할당하도록 생성된 함수는 function 키워드 다음에 함수 이름이 없으므로 익명 함수로 간주한다. 따라서 함수의 name프로퍼티는 빈 문자열이다. 그러므로 함수 표현식은 반드시 호출하기 전에 할당해야한다.
 



7.1 재귀
'재귀 함수'는 함수가 자기 자신을 이름으로 호출하는 형태이다.
function factorial(num){
  if(num <= 1){
    return 1;
  }else{
    return num * arguments.callee(num-1);
    // return num * factoriial(num-1);
  }
}
arguments.calee는 현재 실행중인 함수를 가리키는 포인터이므로 재귀 함수를 사용할 때는 함수 이름 대신 arguments,callee를 권장한다.
 



7.2 클로저
'익명함수'와 '클로저'는 자주 잘못 혼용되지만 '클로저'란 다른 함수의 스코프에 있는 변수에 접근 가능한 함수이다.
클로저를 이해하기 위해서는 스코프 체인이 어떻게 생성되고 사용되는지 알아야 한다. 함수를 호출하면 실행 컨텍스트와 스코프 체인이 생성되고 함수의 활성화 객체는 arguments 및 이름 붙은 매개변수로 초기화 된다.
외부 함수의 활성화 객체는 스코프 체인의 두 번째 객체이고 이 과정이 포함 관계에 있는 함수에서 계속 생성하여 스코프 체인이 전역 실행 컨텍스트에서 종료될 때까지 이어진다.
함수를 실행하면 값을 읽거나  쓸 변수를 스코프 체인에서 검색한다.
스코프 체인이란 변수 객체를 가리키는 포인터 목록이며 객체를 직접 포함하는 것은 아니다.
클로저는 외부 함수의 스코프를 보관해야 하므로 다른 함수에 비해 메모리를 많이 요구한다. 클로저를 사용하면 메모리 문제가 생길 수 있으니 반드시 필요할 때만 사용하길 원한다. 크롬 v8처럼 자바스크립트 코드를 최적화하는 엔진은 클로저 때문에 반환 불가능해진 메모리를 회수하려 시도하기도 하지만 클로저를 쓸 때는 조심하는 편이 상책이다.
 
7.2.1 클로저와 변수
스코프 체인에는 한 가지 눈에 띄는 부작용이 있는데 항상 외부함수의 변수에 마지막으로 저장된 값만 알 수 있다는 점이다.
클로저가 특정 변수가 아니라 전체 변수 객체에 대한 참조를 저장한다는 것을 기억하라.

7.2.2 this 객체
this 객체는 런타임에서 함수가 실행 중인 컨텍스트에 묶인다. 즉 전역함수에서 this는 스트릭트 모드가 아닐 때는 window, 스트릭트 모드에서는 undefined 이며 함수가 객체 메서드로 호출되었을 때 this 는 해당 객체이다.
모든 함수는 호출되는 순간 자동으로 thisarguments 두 특별한 변수를 갖게 되는데 내부 함수는 결코 외부함수의 this, arguments에 직접적으로 접근할 수 없다.  외부 스코프의 매개변수 객체에 접근해야 한다면 클로저에서 접근할 수 있도록 이에 대한 참조를 다른 변수에 저장해야 한다.

7.2.3 메모리 누수
클로저는 인터넷 익스플로러 9 이전 버전에서 메모리 문제를 일으키는데 이는 JScript 객체와 COM 객체에 사용하는 가비지 컬렉션 방법이 다르기 때문이다.
 



7.3 블록 스코프 흉내내기
자바스크립트에는 블록 레벨 스코프라는 개념이 없으므로 블록 문장에서 정의한 변수는 해당 문장이 아니라 외부 함수에 묶여서 그 시점수터 함수 내에서 접근 할수 있게 된다. 이것은 익명 함수를 블록 스코프처럼 쓰는 문법(고유 스코프)으로 해결할 수 있다.
(function(){
  // 코드블록
})();
이 문법에서는 익명 함수를 정의하는 즉시 호출한다. 이를 '즉시 호출 함수'라고 부르기도 한다.
 


 
7.4 고유 변수
함수 안에서 정의한 변수는 함수 밖에서 접근할 수 없으므로 모두 고유 변수라고 간주한다. 함수 내부에서는 고유 변수에 접근 할 수 있지만 함수 밖에서는 불가능하다. 클로저를 이 함수 안에서 만들면 스코프 체인을 통해 이들 변수에 접근할 수 있다.
특권 메서드는 고유 변수.함수에 접근 가능한 공용 메서드로 만드는 방법은 두 가지가 있다.


7.4.1 정적 고유 변수
특권 메서드는 고유 변수나 함수를 정의할 때 쓰는 고유 스코프를 통해서 생성할 수도 있다.

7.4.2 모듈 패턴
모듈 패턴은 객체를 반환하는 익명 함수를 사용한다.
모듈 패턴은 단 하나의 객체를 반드시 생성하고 몇 가지 데이터를 가지며 또한 고유 데이터에 접근 가능한 공용 메서드를 외부에 노출하도록 초기화 해야 할 때 유용하다.

7.4.3 모듈 확장 패턴
객체를 반환하기 전에 확장하는 확장 패턴은 싱글톤 객체가 특정 타입의 인스턴스지만 프로퍼티나 메서드를 추가하여 확장해야 할 때 유용하다.
 
 

 

'나홀로스터디 > JS For Web Dev' 카테고리의 다른 글

클라이언트 감지  (0) 2014.11.20
브라우저 객체모델  (0) 2014.11.12
참조타입  (0) 2014.10.17
객체에 대한 이해  (0) 2014.10.15
변수와 스코프, 메모리  (0) 2014.10.07
Copyright © HuckleberryM All Rights Reserved | JB All In One Designed by CMSFactory.NET