특정 동작을 하는 코드를 모아둔 것
function name(parameter1, parameter2, ... parameterN) {
// 함수 본문
}
함수 내에서 선언한 변수
function showMessage() {
let message = "안녕하세요!"; // 지역 변수
alert( message );
}
showMessage(); // 안녕하세요!
alert( message ); // ReferenceError: message is not defined (message는 함수 내 지역 변수이기 때문에 에러가 발생합니다.)
함수 외부에 선언된 변수
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 으로 값이 바뀜
let userName = 'John';
function showMessage() {
let userName = "Bob"; // 같은 이름을 가진 지역 변수를 선언합니다.
let message = 'Hello, ' + userName; // Bob
alert(message);
}
// 함수는 내부 변수인 userName만 사용합니다,
showMessage();
alert( userName ); // 함수는 외부 변수에 접근하지 않습니다. 따라서 값이 변경되지 않고, John이 출력됩니다.
함수 선언 방식 괄호 사이에 있는 변수
function showMessage(from, text) { // 인자: from, text
alert(from + ': ' + text);
}
showMessage('Ann', 'Hello!'); // Ann: Hello! (*)
showMessage('Ann', "What's up?"); // Ann: What's up? (**)
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given
방법2) if문
function showMessage(text) {
// ...
if (text === undefined) { // 매개변수가 생략되었다면
text = '빈 문자열';
}
alert(text);
}
showMessage(); // 빈 문자열
방법3) 논리연산자 ||
// 매개변수가 생략되었거나 빈 문자열("")이 넘어오면 변수에 '빈 문자열'이 할당됩니다.
function showMessage(text) {
text = text || '빈 문자열';
...
}
방법4) nullish 병합 연산자 ??
function showCount(count) {
alert(count ?? "unknown");
}
함수를 호출했을 때 함수를 호출한 곳에 반환하는 특정값
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3
function doNothing() { /* empty */ }
function doNothing2() {
return;
}
alert( doNothing() === undefined ); // true
alert( doNothing2() === undefined ); // true
자바스크립트는 함수를 특별한 종류의 값으로 취급함
다른 언어에서처럼 "특별한 동작을 하는 구조"로 취급되지 않음
그래서 함수 선언 방식 외에 함수 표현식(Function Expression) 을 사용해서 함수를 만들 수 있음
function sayHi() { // (1) 함수 생성
alert( "Hello" );
}
let func = sayHi; // (2) 함수 복사
func(); // Hello // (3) 복사한 함수를 실행(정상적으로 실행됩니다)!
sayHi(); // Hello // 본래 함수도 정상적으로 실행됩니다.
함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 그 함수를 "나중에 호출(called back)"하는 것이 콜백 함수의 개념
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "동의하셨습니다." );
}
function showCancel() {
alert( "취소 버튼을 누르셨습니다." );
}
// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
함수 표현식보다 단순하고 간결한 문법으로 함수를 만들 수 있는 방법
화살표 함수라는 이름은 문법의 생김새를 차용해 지어졌음
let func = (arg1, arg2, ...argN) => expression
let double = n => n * 2;
// let double = function(n) { return n * 2 }과 거의 동일합니다.
alert( double(3) ); // 6
let sayHi = () => alert("안녕하세요!");
sayHi();
let sum = (a, b) => { // 중괄호는 본문 여러 줄로 구성되어 있음을 알려줍니다.
let result = a + b;
return result; // 중괄호를 사용했다면, return 지시자로 결괏값을 반환해주어야 합니다.
};
alert( sum(1, 2) ); // 3
임의의(정해지지 않은) 수의 인수를 받는 방법
...배열이름
function showName(firstName, lastName, ...titles) {
alert( firstName + ' ' + lastName ); // Bora Lee
// 나머지 인수들은 배열 titles의 요소가 됩니다.
// titles = ["Software Engineer", "Researcher"]
alert( titles[0] ); // Software Engineer
alert( titles[1] ); // Researcher
alert( titles.length ); // 2
}
showName("Bora", "Lee", "Software Engineer", "Researcher");
유사 배열 객체(array-like object)인 arguments를 사용하면 인덱스를 사용해 인수에 접근 가능
function showName() {
alert( arguments.length );
alert( arguments[0] );
alert( arguments[1] );
// arguments는 이터러블 객체이기 때문에
// for(let arg of arguments) alert(arg); 를 사용해 인수를 펼칠 수 있습니다.
}
// 2, Bora, Lee가 출력됨
showName("Bora", "Lee");
// 1, Bora, undefined가 출력됨(두 번째 인수는 없음)
showName("Bora");
let arr = [3, 5, 1];
alert( Math.max(arr) ); // NaN
let arr = [3, 5, 1];
alert( Math.max(...arr) ); // 5 (스프레드 문법이 배열을 인수 목록으로 바꿔주었습니다.)
// 여러 개 전달
alert( Math.max(...arr1, ...arr2) ); // 8
// 일반 값과 혼합
alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25
// 배열 합치기
let merged = [0, ...arr, 2, ...arr2];
let str = "Hello";
// Array.from은 이터러블을 배열로 바꿔줍니다.
alert( Array.from(str) ); // H,e,l,l,o
이런 이유때문에 무언가를 배열로 바꿀 때는 스프레드 문법보다 Array.from이 보편적으로 사용됨!
Object.assign() 말고도 스프레드 문법을 사용하면 배열과 객체를 복사 가능
let arr = [1, 2, 3];
let arrCopy = [...arr]; // 배열을 펼쳐서 각 요소를 분리후, 매개변수 목록으로 만든 다음에
// 매개변수 목록을 새로운 배열에 할당함
// 배열 복사본의 요소가 기존 배열 요소와 진짜 같을까요?
alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true
// 두 배열은 같을까요?
alert(arr === arrCopy); // false (참조가 다름)
// 참조가 다르므로 기존 배열을 수정해도 복사본은 영향을 받지 않습니다.
arr.push(4);
alert(arr); // 1, 2, 3, 4
alert(arrCopy); // 1, 2, 3
이렇게 스프레드 문법을 사용하면 let objCopy = Object.assign({}, obj);
, let arrCopy = Object.assign([], arr);
보다 더 짧은 코드로 배열이나 객체를 복사할 수 있어서 사람들은 이 방법을 선호하는 편