9일차에는 자바스크립트 핸드북 파트4 배운내용을 정리했다.
함수 선언을 할 때는 다음과 같이 2가지 방식이 있다.
// 함수 선언(function declaration)
function sayHi() {
alert( "Hello" );
}
// 함수 표현식(Function Expression)
let sayHi = function() {
alert( "Hello" );
};
let func = sayHi;
// ...
// 함수를 선언할때 매개변수를 넘겨줄 수 있다.
function name(parameter1, parameter2, ... parameterN) {
// 함수 본문
}
함수 내에서 선언한 변수인 지역 변수(local variable)는 함수 안에서만 접근할 수 있다.
function showMessage() {
let message = "안녕하세요!"; // 지역 변수
alert( message );
}
showMessage(); // 안녕하세요!
alert( message ); // ReferenceError: message is not defined (message는 함수 내 지역 변수이기 때문에 에러가 발생합니다.)
함수 내부에서 함수 외부의 변수인 외부 변수(outer variable)에 접근할 수 있습니다.
let userName = 'John';
function showMessage() {
let message = 'Hello, ' + userName;
alert(message);
}
showMessage(); // Hello, John
// 변수의 값을 재할당해 외부변수를 수정할 수 있다.
let userName = 'John';
function showMessage() {
userName = "Bob"; // (1) 외부 변수를 수정함
let message = 'Hello, ' + userName;
alert(message);
}
alert( userName ); // 함수 호출 전이므로 John 이 출력됨
showMessage();
alert( userName ); // 함수에 의해 Bob 으로 값이 바뀜
함수를 호출했을 때 함수를 호출한 그곳에 특정 값을 반환하게 할 수 있다. 이때 이 특정 값을 반환 값(return value)이라고 부른다.
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3
함수가 어떤 동작을 하는지 축약해서 설명해 주는 동사를 접두어로 붙여 함수 이름을 만드는 게 관습이다. 함수에 이름을 지을때는 다음 규칙을 따른다.
showMessage(..) // 메시지를 보여줌
getAge(..) // 나이를 나타내는 값을 얻고 그 값을 반환함
calcSum(..) // 합계를 계산하고 그 결과를 반환함
createForm(..) // form을 생성하고 만들어진 form을 반환함
checkPermission(..) // 승인 여부를 확인하고 true나 false를 반환함
또한 함수는 동작 하나만 담당해야 한다.
함수는 함수 이름에 언급되어 있는 동작을 정확히 수행해야 한다. 그 이외의 동작은 수행해선 안 된다.
독립적인 두 개의 동작은 독립된 함수 두 개에서 나눠서 수행할 수 있게 해야 한다. (이 경우는 제3의 함수를 만들어 그곳에서 두 함수를 호출한다).
밑에 예시처럼 함수 ask의 인수, showOk와 showCancel은 콜백 함수 또는 콜백이라고 부른다.
함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 그 함수를 "나중에 호출(called back)"하는 것이 콜백 함수이다. 아래 예시에선 사용자가 "yes"라고 대답한 경우 showOk가 콜백이 되고, "no"라고 대답한 경우 showCancel가 콜백이 된다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "동의하셨습니다." );
}
function showCancel() {
alert( "취소 버튼을 누르셨습니다." );
}
// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);
익명함수(anonymous function)를 통해 코드를 간결하게 바꿀 수 있다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
ES6부터 나온 문법으로 화살표 기호를 사용하면 코드가 더 간결해진다.
// 문법
let func = (arg1, arg2, ...argN) => expression
// 예시
let sum = (a, b) => a + b;
/* 위 화살표 함수는 아래 함수의 축약 버전입니다.
let sum = function(a, b) {
return a + b;
};
*/
alert( sum(1, 2) ); // 3
인수가 하나라면 다음과 같이 괄호를 생략할 수 있으며
let double = n => n * 2;
// let double = function(n) { return n * 2 }과 거의 동일합니다.
alert( double(3) ); // 6
인수가 없을때 괄호를 비우면 되지만 생략은 불가하다.
let sayHi = () => alert("안녕하세요!");
sayHi();
넘겨주는 매개변수가 많을 때 그 값들을 담을 배열 이름을 마침표 세 개 ...뒤에 붙여주면 함수 선언부에 포함시킬 수 있다. 이때 마침표 세 개 ...는 "남아있는 매개변수들을 한데 모아 배열에 집어넣어라."는 것을 의미한다.
function sumAll(...args) { // args는 배열의 이름입니다.
let sum = 0;
for (let arg of args) sum += arg;
return sum;
}
alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6
나머지 매개변수는 항상 마지막에 넣어줘야 한다.
function f(arg1, ...rest, arg2) { // ...rest 후에 arg2가 있으면 안 됩니다.
// 에러
}
다수의 인수를 받는 함수에 배열을 전달할 때 스프레드 문법을 사용한다.
let arr = [3, 5, 1];
alert( Math.max(...arr) ); // 5 (스프레드 문법이 배열을 인수 목록으로 바꿔주었습니다.)
// 이터러블객체 여러개를 전달할 수 있다.
let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];
alert( Math.max(...arr1, ...arr2) ); // 8
// 스프레드 문법을 평범한 값과 혼합해 사용할 수도 있다.
let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];
alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25
// 스프레드 문법은 배열을 합칠 때도 사용할 수 있다.
let arr = [3, 5, 1];
let arr2 = [8, 9, 15];
let merged = [0, ...arr, 2, ...arr2];
alert(merged); // 0,3,5,1,2,8,9,15 (0, arr, 2, arr2 순서로 합쳐집니다.)
함수에 관해서 학습해봤는데 함수에 이름 짓는 방법이나, 함수에 역할에 대해 꼼꼼하게 배울 수 있어서 좋았다.