![article thumbnail image](https://blog.kakaocdn.net/dn/D6Ohx/btq3JTdAe2n/C9V7sNWNT9CiF0kJnh3Yt0/img.png)
함수
함수는 프로그램을 구성하는 주요 '구성 요소(building block)'이다. 함수를 이용하면 중복 없이 유사한 동작을 하는 코드를 여러 번 호출할 수 있다.
함수 선언
function name(parameters) {
// 함수 본문
}
function
키워드, 함수 이름, 괄호로 둘러싼 매개변수를 차례로 쓰면 함수를 선언할 수 있다.
매개변수가 없을 수도 있으며, 만약 매개변수가 여러 개 있다면 각 매개변수를 콤마로 구분한다.
이어서 함수 본문(body)을 중괄호로 감싸 붙여 주면 된다.
새롭게 정의한 함수는 함수 이름 옆에 괄호와 매개변수를 붙여서 호출할 수 있다.
function showMessage() {
alert("안녕하세요!");
}
showMessage();
showMessage();
지역 변수
함수 내에서 선언한 변수인 지역 변수(local variable)는 함수 안에서만 접근할 수 있다.
function showMessage() {
let message = "Hello, I'm JavaScript!"; // local variable
alert(message);
}
showMessage(); // Hello, I'm JavaScript!
alert(message); // <- error!
외부 변수
함수 내부에서 함수 외부의 변수인 외부 변수(outer variable)에 접근할 수 있다.
let userName = 'John';
function showMessageName() {
userName = "Bob"; // 외부 변수 수정 가능
let message = "Hello, " + userName;
alert(message);
}
alert(userName); // 함수 호출 전이므로 John이 출력된다.
showMessageName(); // Bob 변경 후, Hello, Bob이 출력된다.
alert(userName); // 함수에 의해 Bob으로 값이 변경되었다.
외부 변수는 동일한 이름의 지역 변수가 없는 경우에만 사용할 수 있다.
함수 내부에 외부 변수와 동일한 이름을 가진 변수가 선언되었다면, 해당 내부 변수가 외부 변수를 가린다.
function showMessageName2() {
let userName = "Bob"; // 같은 이름을 가진 지역 변수를 선언하면,
let message = "Hello, " + userName; // 지역 변수를 우선시하게 된다.
alert(message);
}
전역 변수
위 예시의 userName
처럼, 함수 외부에 선언된 변수는 전역 변수(global variable)라고 부른다.
전역 변수는 같은 이름을 가진 지역 변수에 의해 가려지지만 않는다면 모든 함수에서 접근할 수 있다.
단, 변수는 연관되는 함수 내에 선언하고 전역 변수는 되도록이면 사용하지 않는 편이 좋다.
프로젝트 전반적으로 사용되는 데이터는 전역 변수에 저장하는 게 유용한 경우도 존재한다.
매개변수
매개변수(parameter)를 이용하면 임의의 데이터를 함수 안에 전달할 수 있다.
function showMessage(from, text) {
alert(from + ": " + text);
}
showMessage("Ann", "Hello!");
showMessage("Ann", "What's up?");
함수에 전달된 인자는 지역변수 from
과 text
에 복사되고, 그 후 함수는 지역 변수에 복사된 값을 사용한다.
이렇게 지역 변수로의 복사를 하기 때문에, 함수 내부에서 변수의 값을 변경해도 함수 바깥의 원래 매개변수가 변경되지는 않음에 유의한다.
function showMessage(from, text) {
from = '*' + from + "*";
alert (from + ": " + text);
}
let from = "Ann";
showMessage(from, "Hello"); // *Ann*: Hello
// 함수는 복사된 값을 사용하기 때문에 함수 바깥의 "from"은 값이 변경되지 않는다.
alert(from); // Ann
기본값
매개변수에 값을 전달하지 않으면 그 값은 undefined
가 된다. (에러 없음)
showMessage("Ann"); // Ann: undefined
매개변수에 값을 전달하지 않아도 그 값이 undefined
가 되지 않게 하려면, 다음과 같이 '기본값(default value)'을 설정해 준다.
function showMessage(from, text = "no text given") {
alert(from + ": " + text);
}
showMessage("Ann"); // Ann: no text given
아래와 같이 복잡한 표현식도 기본값으로 설정할 수 있다.
function showMessage(from, text = anotherFunction()) {
// anotherFunction()은 text 값이 없을 때만 호출 됨
// anotherFunction()의 반환값이 text의 값이 됨
}
매개변수 기본값을 설정할 수 있는 또다른 방법
function showMessage(text) {
if (text == undefined) {
text = 'empty message';
}
}
function showMessage(text) {
text = text || 'empty';
}
null 병합 연산자(nullish coalescing operator) ??
를 사용하면 0
처럼 falsy로 평가되는 값들을 일반 값처럼 처리할 수 있어서 좋다.
function showCount(count) {
alert(count ?? "unknown");
}
showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown
반환 값
함수를 호출했을 때, 해당 함수를 호출한 곳에 특정 반환 값(return value)을 돌려줄 수 있다.
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert(result); // 3
return
지시자는 함수 내 어디서든 사용 가능하다. return
을 만나면 함수 실행이 즉시 중단되며, 함수를 호출한 곳에 값을 반환하게 된다.
function checkAge(age) {
if (age >= 18) {
return true;
} else {
return confirm("Do you have permission from your parents?");
}
}
let age = prompt("How old are you?", 18);
if (checkAge(age)) {
alert("Access granted");
} else {
alert("Access denied");
}
반환값 없이 return
만 해서 함수를 즉시 종료하는 것도 가능하다.
function showMovie(age) {
if (!checkAge(age)) {
return;
}
alert("Showing you the movie");
// ...
}
return
문이 없는 함수도 undefined
를 반환한다.
function doNothing() { /* empty */ }
alert(doNothing() === undefined); // true
return
지시자만 있는 경우에도 undefined
를 반환한다. return
== return undefined
.
function doNothing() {
return;
}
alert(doNothing() === undefined); // true
return과 값 사이에 절대 줄 삽입을 하지 말자.
return//; // enter를 넣게 되면 세미콜론이 붙은 것과 동일하게 동작한다.
(some + long + expression + or + whatever * f(a) + f(b))
return ( // multi-line으로 작성하고 싶은 경우, 다음과 같이 작성한다.
some + long +
expression +
or +
whatever * f(a) + f(b)
)
함수 이름 짓기
함수는 어떤 동작을 수행하기 위한 코드이기 때문에, 함수의 이름은 대개 동사이다.
함수 이름은 가능한 간결하고 명확해야 하며, 함수 이름만 보고도 어떤 기능을 하는지 나타낼 수 있어야 한다.
showMessage(); // 메시지를 보여 준다.
getAge(); // 나이를 나타내는 값을 얻고, 그 값을 반환한다.
calcSum(); // 합계를 계산하고, 그 결과값을 반환한다.
createForm(); // form을 생성하고, 만들어진 form을 반환한다.
checkPermission(); // 승인 여부를 확인하고, true나 false를 반환한다.
함수는 동작 하나만 담당해야 한다.
독립적인 두 개의 동작은 독립된 함수 두 개에서 나누어 수행할 수 있게 해야 한다.
getAge
함수는 나이를 얻어오는 동작만 수행해야 한다.alert
창에 나이를 출력하는 동작은 이 함수에서 처리하지 않는 게 좋다.createForm
함수는 form을 만들고 이를 반환하는 동작만 해야 한다. form을 문서에 추가하는 동작이 해당 함수에 들어가 있으면 좋지 않다.
팀에서 만든 접두어 규칙이 있다면 해당 규칙을 반드시 따라야 한다.
함수 == 주석
함수가 길어지면 함수를 잘게 쪼갤 때가 되었다는 신호로 받아들여야 한다. 함수를 쪼개는 게 쉬운 작업은 아니지만, 분리하여 작성하면 많은 작성이 있기 때문에 분리하는 것을 권장한다.
간결한 함수는 테스트와 디버깅을 쉽게 한다. 그리고 함수 자체로도 주석의 역할까지 한다.
function showPrimes(n) {
nextPrime: for (let i = 2; i < n; ++i) {
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert(i); // 소수
}
}
function showPrimes(n) {
for (let i = 2; i < n; ++i) {
if (!isPrime(i)) continue;
alert(i);
}
}
function isPrime(n) {
for (let i = 2; i < n; ++i) {
if (n % i == 0) return false;
}
return true;
}
요약
function 함수이름(복수의, 매개변수) {
/* 함수 본문 */
}
- 함수에 전달된 매개변수는 복사를 거쳐 함수의 지역변수가 된다.
- 함수에서 외부 변수에 접근할 수 있다. 단, 함수 밖에서 함수의 지역변수에 접근하는 건 불가능하다.
- 함수는 값을 반환할 수 있다. 값을 반환하지 않는 경우,
return undefined
와 동일하다.
과제
"else"는 정말 필요한가요?
function checkAge(age) {
if (age > 18) {
return true;
} else {
// ...
return confirm('보호자의 동의를 받으셨나요?');
}
}
function checkAge(age) {
if (age > 18) {
return true; // 18세 이상은 여기서 return 처리가 되기 때문에
} // else문이 없어도 18세 미만은
return confirm('보호자의 동의를 받으셨나요?'); // 해당 return 처리된다
}
'?'나 '||'를 사용하여 함수 다시 작성하기
function checkAge(age) {
if (age > 18) {
return true;
} else {
return confirm('보호자의 동의를 받으셨나요?');
}
}
function checkAge(age) {
return age > 18 ? true : confirm('보호자의 동의를 받으셨나요?');
}
function checkAge(age) {
return age > 18 || confirm('보호자의 동의를 받으셨나요?');
}
min(a, b) 함수 만들기
- 다음과 같이 동작하는 함수 만들기
min(2, 5) == 2
min(3, -1) == -1
min(1, 1) == 1
function min(a, b) {
return a < b ? a : b;
}
pow(x, n) 함수 만들기
function showPrompt() {
let x = prompt("x를 입력하세요.", '');
if (x == undefined || x == '') {
alert("유효하지 않은 x입니다.");
return;
}
let n = prompt("n을 입력하세요.", '');
if (n == undefined || n == '' || n < 1) {
alert("유효하지 않은 n입니다. \n자연수를 입력해 주세요.");
return;
}
alert(pow(x, n));
}
function pow(x, n) {
let result = x;
for (let i = 1; i < n; ++i) {
result *= x;
}
return result;
}
showPrompt();
해당 포스트는 'The Modern JavaScript Tutorial' 문서를 읽으며 개인 백업용으로 메모하였습니다.
The Modern JavaScript Tutorial
We want to make this open-source project available for people all around the world. Help to translate the content of this tutorial to your language!
javascript.info