이미 6장에서 설명한 바와 같이 함수를 정의하는 가장 일반적인 방법은 function문을 사용하는 것이다.
이 문법은 function 키워드로 시작하며 다음과 같은 항목들이 따라온다.
- 함수의 이름
- 괄호 () 안에 0개 혹은 임의 개수의 매개변수 이름을 쉼표로 분리한 목록
- 중괄호 {} 안에 함수의 몸체를 구성하는 자바스크립트 문장들
예 8-1은 몇몇 함수들의 정의를 보여 준다.
이 예에 소개된 함수들은 모두 짧고 단순하지만 위에서 소개한 함수 정의의 구성요소들을 전부 담고 있다.
함수는 임의 개수의 전달인자를 가질 수 있으며 return 문을 반드시 사용할 필요는 없다는데 주목하라.
6장에서 소개한 return 문은 함수의 실행을 멈추고 return 문에 주어진 표현식의 결과값 (만약 표현식이 주어졌다면)을 함수의 호출자에게 전달하는 역할을 한다.
// document.write() 함수 대신에 사용할 수 있는 간단한 함수.
// 이 함수에는 return 문이 없다. 따라서 undefined 값을 반환한다.
function print(msg){
// 두 점 사이의 거리를 계산하여 반환하는 함수.
function distance(x1, y1, x2, y2){
var dy = y2 - y1;
return Math.sqrt(dx*dx + dy*dy);
// 계승(factorial) 팩토리얼 값을 계산하는 재귀 함수(자기 자신을 호출하는 함수)
// x!는 x와 x보다 작은 모든 양의 정수를 곱한 값이다.
function factorial(x){
만약 return 문에 연결된 표현식이 없다면 함수는 undefined 값을 반환한다.
5장에서 소개한 바와 같이, 한 번 정의된 함수는 () 연산자와 함께 호출한다.
print("Welcome to my blog!"); // "제 블로그에 오신 것을 환영합니다!"
total_dist = distance(0,0,2,1) + distance(2,1,3,5);
print("The probability of that is: " + factorial(5)/factorial(13));
함수를 호출할 때 괄호 사이에 명시한 각 표현식은 일단 평가된 후 그 결과값이 함수의 전달인자로써 사용된다. 이러한 값은 함수를 정의할 때 이름 붙여놓은 매개변수로 할당이 되며 함수는 자신의 매개변수들을 사용하기 위하여 매개변수의 이름을 참조한다. 일반적으로 매개변수는 실행되는 함수의 몸체 안에서만 유효하며 함수의 밖에서 또는 함수가 반환한 후에는 접근할 수 없음을 유의하라(중요한 예외 상황이 있는데,
자바스크립트는 데이터 타입 제약이 느슨한 언어이기 때문에 함수 매개변수의 데이터 타입을 명시하지 않아도 좋다. 자바스크립트는 함수가 기대하는 타입의 데이터를 전달하는지 검사하지도 않는다. 만약 전달인자의 데이터 타입이 중요하다면 typeof 연산자를 사용하여 직접 테스트할 수 있다. 또한 자바스크립트는 정확한
예 8-1에서 정의한 print() 함수에 return 문에 없다는 점을 주목하라.
1. 중첩된 함수
자바스크립트에서 함수는 다른 함수 안에 중첩되어 정의될 수 있다. 예를 들면 다음과 같다.
return Math.sqrt(square(a) + square(b));
중첩된 함수는 그 함수가 중첩되어 위치하는 함수의 최상위 레벨에서만 정의될 수 있다.
즉 if문이나 while 루프의 몸체 같은 문장 블록 안에서는 정의될 수 없다.[각주:1]
이러한 제약은 오직 function 문에 의한 함수 정의에만 해당한다.
다음 절에서 소개하는 함수 리터럴은 어디에든 위치할 수 있다.
몇몇 흥미로운 프로그램 작성 기법에는 중첩된 함수를 사용하기도 한다.
이것은 이 장의 후반부에서 더 설명하겠다.
- 자바스크립트의 다른 구현에서는 표준에서 요구하는 것보다 더 관대한 형태의 함수 정의를 지원할 수 있다. 예를 들어 자바스크립트 1.5의 넷스케이프 구현에서는 if문 안에서 등장하는 '조건부 함수 정의'를 허용한다. [본문으로]
2. 함수 리터럴
자바스크립트는 함수 리터럴을 사용하여 함수를 정의하는 방법도 제공한다.
3장에서 이미 소개한 바와 같이 함수 리터럴은 이름 없는 함수를 정의하는데 사용되는 표현식이다.
함수 리터럴의 문법은 문장이 아니라 표현식으로 사용된다는 것과 함수 이름이 없다는 것을 제외하면 function 문과 매우 유사하다.
다음 두 줄의 코드는 function 문과 함수 리터럴을 사용하여 거의 동일한 함수를 정의하는 에를 보여 준다.
var f = function(x) { return x*x; }; // 함수 리터럴
함수 리터럴은 비록 이름 없는 함수를 생성하지만 함수 리터럴의 문법은 선택적으로 함수 이름을 지정하는 것도 허용한다. 이는 재귀 함수를 작성할 때에 유용하다. 예를 들면 다음과 같다.
위의 코드는 이름 없는 함수를 생성하고 이 함수에 대한 참조를 변수f에 저장한다. 함수에 대한 참조를 fact 변수에 저장하지는 않지만 함수의 몸체 안에서 자신을 참조하기 위해 이 이름을 사용하는 것은 허용한다. 하지만 이렇게 이름 붙은 함수 리터럴은 자바스크립트 1.5 이전에서는 제대로 구현되어 있지 않다는 사실을
주의하자.
함수 리터럴은 자바스크립트 문장이 아니라 표현식으로 생성된다. 따라서 함수 리터럴은 매우 유연하며, 또한 한 번만 사용되고 버려지기 때문에 이름 붙이지 않아도 되는 일회용 함수를 정의하는 데 적합하다. 예를 들어 함수 리터럴 표현식에 의해 기술된 함수는, 변수에 저장될 수 있고 다른 함수에 전달인자로써 전달될 수 도 있으며 곧바로 호출될 수도 있다.
a.sort(function(a,b) {return a-b;}); // 함수를 정의하여 이를 다른 함수에 전달한다.
var tensquared = (function (x) {return x*x;})(1); // 정의하여 바로 호출한다.
3. 함수 이름 붙이기
모든 적법한 자바스크립트 식벽자가 함수의 이름으로 사용될 수 있다.
너무 간결한 이름보다는 함수를 잘 설명할 수 있는 이름을 사용하라.
이 둘 사이의 가장 적절한 균형은 경험에서 우러나온다.
잘 선택한 함수 이름은 코드 가독성과 유지보수의 측면에서 매우 큰 차이를 만들어낼 수 있다.
함수 이름은 일반적으로 동사 혹은 동사로 시작하는 구절이다. 관습적으로 함수 이름은 소문자로 시작한다. 함수 이름이 둘 이상의 단어를 포함할 때엔 단어와 단어를 like_this() 같이 밑줄 문자로 연결하거나
likeThis() 같이 첫 번째 단어 이후의 모든 단어를 대문자로 시작하는 관습이 있다.
내부적으로만 사용하거나 숨겨진 함수로 사용하려면 밑줄 문자로 함수 이름을 시작한다.
몇몇 프로그램 작성 스타일이나 잘 정의된 프로그램 작성 프레임워크에서는, 빈번하게 사용되는 함수에
매우 짧은 이름을 붙여 사용하는 것이 유용할 수도 있다. 예를 들어 클라이언트 측 자바스크립트 프레임워크
프로토타입(http://prototype.org)에서는, document.getElementById() 같이 빈번하게 사용되지만 키보드로 타이핑 하기엔 어려운 이름에 대한 지능적인 대안으로서, 우아하게 $()라는 함수 이름을 사용하기도 한다.
(2장에서 알아본 바와 같이 달러 기호와 밑줄 문자는 영문자와 숫자 외에 자바스크립트 식별자로 적법한 두 특수 문자다)
'IT_Programming > JavaScript' 카테고리의 다른 글
자바스크립트 완벽가이드 - 8.3 데이터로서의 함수 (0) | 2010.07.04 |
---|---|
자바스크립트 완벽가이드 - 8.2 함수 전달인자 (0) | 2010.07.04 |
자바스크립트 완벽가이드 - 7.8 배열과 유사한 객체 (0) | 2010.07.04 |
자바스크립트 완벽가이드 - 7.7 배열 메서드 (0) | 2010.07.04 |
자바스크립트 완벽가이드 - 7.6 배열 원소 읽고 쓰기 (0) | 2010.07.04 |