
1. 함수
함수는 프로그램을 구성하는 주요 '구성 요소(building block)'이다. 함수를 이용하면 중복 없이 유사한 동작을 하는 코드를 여러 번 호출할 수 있다.
1.1. 함수 선언
function name(parameters) {
// 함수 본문
}
function
키워드, 함수 이름, 괄호로 둘러싼 매개변수를 차례로 쓰면 함수를 선언할 수 있다.
매개변수가 없을 수도 있으며, 만약 매개변수가 여러 개 있다면 각 매개변수를 콤마로 구분한다.
이어서 함수 본문(body)을 중괄호로 감싸 붙여 주면 된다.
새롭게 정의한 함수는 함수 이름 옆에 괄호와 매개변수를 붙여서 호출할 수 있다.
function showMessage() {
alert("안녕하세요!");
}
showMessage();
showMessage();
1.2. 지역 변수
함수 내에서 선언한 변수인 지역 변수(local variable)는 함수 안에서만 접근할 수 있다.
function showMessage() {
let message = "Hello, I'm JavaScript!"; // local variable
alert(message);
}
showMessage(); // Hello, I'm JavaScript!
alert(message); // <- error!
1.3. 외부 변수
함수 내부에서 함수 외부의 변수인 외부 변수(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);
}
1.4. 전역 변수
위 예시의 userName
처럼, 함수 외부에 선언된 변수는 전역 변수(global variable)라고 부른다.
전역 변수는 같은 이름을 가진 지역 변수에 의해 가려지지만 않는다면 모든 함수에서 접근할 수 있다.
단, 변수는 연관되는 함수 내에 선언하고 전역 변수는 되도록이면 사용하지 않는 편이 좋다.
프로젝트 전반적으로 사용되는 데이터는 전역 변수에 저장하는 게 유용한 경우도 존재한다.
1.5. 매개변수
매개변수(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
1.6. 기본값
매개변수에 값을 전달하지 않으면 그 값은 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의 값이 됨
}
1.7. 매개변수 기본값을 설정할 수 있는 또다른 방법
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
1.8. 반환 값
함수를 호출했을 때, 해당 함수를 호출한 곳에 특정 반환 값(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)
)
1.9. 함수 이름 짓기
함수는 어떤 동작을 수행하기 위한 코드이기 때문에, 함수의 이름은 대개 동사이다.
함수 이름은 가능한 간결하고 명확해야 하며, 함수 이름만 보고도 어떤 기능을 하는지 나타낼 수 있어야 한다.
showMessage(); // 메시지를 보여 준다.
getAge(); // 나이를 나타내는 값을 얻고, 그 값을 반환한다.
calcSum(); // 합계를 계산하고, 그 결과값을 반환한다.
createForm(); // form을 생성하고, 만들어진 form을 반환한다.
checkPermission(); // 승인 여부를 확인하고, true나 false를 반환한다.
함수는 동작 하나만 담당해야 한다.
독립적인 두 개의 동작은 독립된 함수 두 개에서 나누어 수행할 수 있게 해야 한다.
getAge
함수는 나이를 얻어오는 동작만 수행해야 한다.alert
창에 나이를 출력하는 동작은 이 함수에서 처리하지 않는 게 좋다.createForm
함수는 form을 만들고 이를 반환하는 동작만 해야 한다. form을 문서에 추가하는 동작이 해당 함수에 들어가 있으면 좋지 않다.
팀에서 만든 접두어 규칙이 있다면 해당 규칙을 반드시 따라야 한다.
1.10. 함수 == 주석
함수가 길어지면 함수를 잘게 쪼갤 때가 되었다는 신호로 받아들여야 한다. 함수를 쪼개는 게 쉬운 작업은 아니지만, 분리하여 작성하면 많은 작성이 있기 때문에 분리하는 것을 권장한다.
간결한 함수는 테스트와 디버깅을 쉽게 한다. 그리고 함수 자체로도 주석의 역할까지 한다.
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;
}
2. 요약
function 함수이름(복수의, 매개변수) {
/* 함수 본문 */
}
- 함수에 전달된 매개변수는 복사를 거쳐 함수의 지역변수가 된다.
- 함수에서 외부 변수에 접근할 수 있다. 단, 함수 밖에서 함수의 지역변수에 접근하는 건 불가능하다.
- 함수는 값을 반환할 수 있다. 값을 반환하지 않는 경우,
return undefined
와 동일하다.
3. 과제
3.1. "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 처리된다
}
3.2. '?'나 '||'를 사용하여 함수 다시 작성하기
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('보호자의 동의를 받으셨나요?');
}
3.3. 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