1. 개요
함수는 특별한 목적의 작업을 수행하도록 설계된 독립적인 블록을 의미한다.
JavaScript에서 함수도 하나의 데이터 타입에 해당한다. 따라서 함수를 변수에 대입하거나 함수를 프로퍼티에 지정하는 것도 가능하다.
또한 데이터 타입으로 규정되었으므로 함수 내에 다른 함수를 중첩하여 정의하는 것도 가능하다.
2. 함수 선언과 사용
function 함수 이름(매개변수 목록){실행문}
함수는 데이터의 한 종류이기 때문에 위와 같이 타입, 이름, 구성 요소로 정의할 수 있다.
매개변수는 함수가 값을 취해서 조작할 데이터 혹은 상태를 말한다.
실행문은 매개 변수로 취해온 값을 연산하여 반환하거나 혹은 반환없이 동작만 수행할 수도 있다.
// addNum라는 이름의 함수를 정의함.
function addNum(x, y) { // x, y는 이 함수의 매개변수임.
document.write(x + y);
}
addNum(2, 3); // addNum() 함수에 인수로 2와 3을 전달하여 호출함.
위와 같이 함수를 선언하면 하단의 실행문을 수행한다.
매개변수는 별도로 지정한 ‘변수’도 가능하고 값 자체를 할당하는 것도 가능하다.
함수는 기본적으로 선언된 상태에서 해당 함수의 이름과 매개변수를 대입하여 호출한다.
물론 매개변수가 없는 경우에도 호출은 가능하며, 만약 값을 반환한다면 해당 함수는 함수 자체로 ‘값’의 역할을 할 수 있다.
function sqr(x) { // 제곱의 값을 구하는 함수 sqr를 정의함.
return x * x;
}
var sqrNum = sqr; // 변수 sqrNum에 함수 sqr을 대입함.
document.write(sqrNum(4)); // 변수 sqrNum를 함수처럼 호출함.
3. 변수의 유효 범위(variable scope)
자바스크립트에서 객체나 함수는 모두 변수에 해당한다.
변수의 유효 범위는 해당 변수에 접근할 수 있는 영역을 말한다.
전역 변수와 지역 변수로 나뉘는데, 전역 변수는 모든 영역에서 접근이 가능한 변수를 말하고, 지역 변수는 함수나 메소드 제어문에 사용되어 해당 블록((), {} 등)에서만 사용되는 변수를 말한다.
function localNum() {
var num = 10; // 지역 변수 num에 숫자 10을 대입함.
document.write("함수 내부에서 변수 num의 타입은 " + typeof num + "입니다.<br>"); // number
}
localNum(); // 함수 localNum()을 호출함.
document.write("함수의 호출이 끝난 뒤 변수 num의 타입은 " + typeof num + "입니다."); // undefined
var num = 10; // 전역 변수 num을 선언함.
function globalNum() {
document.write("함수 내부에서 변수 num의 값은 " + num + "입니다.<br>"); // 10
num = 20; // 전역 변수 num의 값을 함수 내부에서 변경함.
}
globalNum(); // 함수 globalNum()을 호출함.
document.write("함수의 호출이 끝난 뒤 변수 num의 값은 " + num + "입니다."); // 20
지역 변수와 전역 변수를 구분할 수 있는 것은 알고리즘 구성에 굉장히 중요하며, 변수의 선언 위치에 따라 알고리즘이나 코드의 해석, 유지 보수가 변하니 반드시 이해해야한다.
물론 자바스크립트는 호이스팅이라는 특수한 과정을 거쳐 브라우저에서 해석되므로 지역변수와 전역변수 사이에 다른 프로그래밍과 상반되는 규칙이 적용되기도 한다.
다만 호이스팅의 우선 순위는 실제 코딩과 동작 이해에 크게 도움이 되지 않는다.
정확히는 해당 현상을 이해하는 정도로도 충분히 기능을 구현할 수 있다는 말이다.
4. 매개변수와 인수
매개변수(parameter)는 함수에서 실행문을 처리하기 위해 전달되는 값을 말한다.
자바스크립트는 매개변수의 타입을 별도로 지정하지 않기 때문에 인수를 원인으로 하는 ‘오류’에서 비교적 자유로운 편이다.
문제는 이러한 상황에서 자바스크립트는 해당 함수를 매개변수에 따라 처리하는 것이 아니라 부족한 데이터를 undefined로 설정한다는 것이다.
한마디로 함수에서 ‘매개변수’로 문제가 발생하면 이를 찾고 유지보수하기가 힘들다는 것이니 반드시 매개변수에 전달되는 인수가 올바른지 확인할 필요가 있다.
function addNum(x, y, z) { // x, y, z라는 3개의 매개변수를 가지는 함수 addNum()을 정의함.
return x + y + z;
}
addNum(1, 2, 3); // 인수로 1, 2, 3을 전달하여 함수를 호출함. -> 6
addNum(1, 2); // 인수로 1, 2을 전달하여 함수를 호출함. -> NaN
addNum(1); // 인수로 1을 전달하여 함수를 호출함. -> NaN
addNum(); // 인수로 아무것도 전달하지 않고 함수를 호출함. -> NaN
물론 해당 함수에 if문(if(x === undefined){x=0})을 작성하여 undefined 값을 강제로 ‘0’ 혹은 임의 숫자로 할당할 수도 있다.
반대로 더 많은 인수가 매개변수에 할당되는 경우, 매개변수에 대입되지 못한 인수들은 참조할 방법이 없게 된다.
이를 방지할 수 있는 방법이 arguments 객체인데, 아규먼트 객체는 인수로 전달된 값을 저장할 수 있는 ‘배열’을 말한다.
배열을 별도로 할당하지 않아도 선언 및 사용이 가능한 장점이 있다.
function addNum() {
var sum = 0; // 합을 저장할 변수 sum을 선언함.
for(var i = 0; i < arguments.length; i++) { // 전달받은 인수의 총 수만큼 반복함.
sum += arguments[i]; // 전달받은 각각의 인수를 sum에 더함.
}
return sum;
}
addNum(1, 2, 3); // 6
addNum(1, 2); // 3
addNum(1); // 1
addNum(); // 0
addNum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 55
5. 디폴트 매개변수와 나머지 매개변수
디폴트 매개변수는 ECMAScript 6부터 추가된 기능으로 매개변수가 전달되지 않았을 때 자동으로 ‘인수’를 할당하는 기능을 말한다.
자바스크립트의 매개변수의 기본값은 undefined 이므로 이런 경우, if를 대입하여 별도의 제어문을 설정해야했다.
function mul(a, b) {
// 인수가 한 개만 전달되었을 때 나머지 매개변수의 값을 undefined 값이 아닌 1로 설정함.
b = (typeof b !== 'undefined') ? b : 1;
return a * b;
}
mul(3, 4); // 12
mul(3); // 3
function mul(a, b = 1) { // 인수가 한 개만 전달되면 나머지 매개변수의 값을 언제나 1로 설정해 줌.
return a * b;
}
mul(3, 4); // 12
mul(3); // 3
디폴트 매개변수를 이용하면 더욱 쉽게 함수 사용이 가능하다.
나머지 매개변수는 생략 접두사(...)를 사용하여 특정 위치의 인수부터 마지막 인수까지를 한 번에 지정하는 것을 말한다.
function sub() {
var firstNum = arguments[0]; // 첫 번째 인수에서
for(var i = 0; i < arguments.length-1; i++) { // 두 번째부터 마지막 인수까지를
firstNum -= arguments[i+1]; // 뺌.
}
return firstNum;
}
sub(10, 2, 3); // 10 - 2 - 3 = 5
sub(10, 1, 5, 8); // 10 - 1 - 5 - 8 = -4
// 첫 번째 인수를 변수 firstNum에 저장하고 나머지 인수들은 배열 restArgs에 저장함.
function sub(firstNum, ...restArgs) {
for(var i = 0; i < restArgs.length; i++) {
firstNum -= restArgs[i];
}
return firstNum;
}
sub(10, 2, 3); // 10 - 2 - 3 = 5
sub(10, 1, 5, 8); // 10 - 1 - 5 - 8 = -4
6. 미리 정의된 전역 함수(predefined functions)
함수 | 기능 |
eval() | eval() 함수는 문자열로 표현된 자바스크립트 코드를 실행하는 함수이다. |
isFinite() | isFinite() 함수는 전달된 값이 유한한 수인지를 검사하여 그 결과를 반환한다. 만약 인수로 전달된 값이 숫자가 아니라면, 숫자로 변환하여 검사한다. |
isNaN() | isNaN() 함수는 전달된 값이 NaN인지를 검사하여 그 결과를 반환한다. 만약 인수로 전달된 값이 숫자가 아니라면, 숫자로 강제 변환하여 검사한다. 전달된 값이 숫자인지 아닌지를 확인하기 위하여 typeof 연산자를 대신 사용할 수도 있다. |
parseFloat() | parseFloat() 함수는 문자열을 파싱하여 부동 소수점 수(floating point number)로 반환한다. |
parseInt() | parseInt() 함수는 문자열을 파싱하여 정수로 반환한다. 전달받은 문자열의 시작이 "0x"로 시작하면, parseInt() 함수는 해당 문자열을 16진수로 인식한다. |
decodeURI() | encodeURI() 함수는 URI에서 주소를 표시하는 특수문자를 제외하고, 모든 문자를 이스케이프 시퀀스(escape sequences) 처리하여 부호화한다. |
decodeURIComponent() | encodeURIComponent() 함수는 URI에서 encodeURI() 함수에서 부호화하지 않은 모든 문자까지 포함하여 이스케이프 시퀀스 처리한다. |
encodeURI() | decodeURI() 함수는 encodeURI() 함수나 다른 방법으로 만들어진 URI(Uniform Resource Identifier)를 해독한다. |
encodeURIComponent() | decodeURIComponent() 함수는 encodeURIComponent() 함수나 다른 방법으로 만들어진 URI 컴포넌트를 해독한다. |
escape() | escape() 함수는 전달받은 문자열에서 특정 문자들을 16진법 이스케이프 시퀀스 문자로 변환한다. |
unescape() | unescape() 함수는 전달받은 문자열에서 escape() 함수나 다른 방법으로 만들어진 16진법 이스케이프 시퀀스 문자를 원래의 문자로 변환한다. |
Number() | Number() 함수는 전달받은 객체의 값을 숫자로 반환한다. |
String() | String() 함수는 전달받은 객체의 값을 문자열로 반환한다. |
'JavaScript > 기본 이론' 카테고리의 다른 글
Chapter 12. 변수와 호이스팅 (0) | 2021.11.28 |
---|---|
Chapter 11. canvas (객체의 기본 이해) (0) | 2021.11.27 |
Chapter 09. 동작에 따라 데이터를 변화시키는 방법 (0) | 2021.11.25 |
Chapter 08. 데이터를 추출하는 방법 (DOM 기초 2) (0) | 2021.11.24 |
Chapter 07. 배열 변수 (0) | 2021.11.23 |