함수
스크립트 작성시 유사한 동작을 하는 코드가 여러 곳에서 필요할 때가 있다. 함수를 이용하면 중복 없이 유사한 동작을 하는 코드를 여러 번 호출할 수 있다.
함수 선언(함수 선언문)
함수 선언 방식을 이용하여 함수를 만들 수 있다.
function showMsg() {
alert('hi');
}
// 파라미터가 있는 경우
function name(param1, param2) {
// 본문
}
지역 변수
함수 내에서 선언한 변수를 지역 변수(local variable)라 칭하며 지역 변수는 함수 안에서만 접근할 수 있다.
function showMsg() {
let msg = 'hi';
alert(msg);
}
showMsg(); // hi
alert(msg); // error
외부 변수
함수 내부에서는 함수 외부의변수인 외부 변수(outer variable)에 접근할 수 있다. 또한 외부 변수에 접근하는 것 뿐만 아니라 수정도 가능하다.
let userName = 'syong';
function showMsg() {
let msg = 'hi, ' + userName;
alert(msg);
}
showMsg(); // hi, syong
외부 변수는 지역 변수가 없는 경우에만 사용가능하다. 함수 내부에 외부 변수와 동일한 이름을 가진 변수가 선언되어 있는 경우, 내부 변수는 외부 변수를 가린다.
let userName = 'syong';
function showMsg() {
let userName = 'bae';
alert(userName); // bae
}
showMsg(); // bae
alert(userName); // syong
userName처럼 함수 외부에 선언된 변수를 전역 변수라고 칭한다. 전역 변수는 되도록 사용하지 않거나 최소한으로 사용하는 것이 좋다. 다만 프로젝트 전반에서 사용되는 데이터라면 전역 변수를 선언하는 것이 유용한 경우도 있다.
매개변수
매개변수(parameter)를 이용하여 임의의 데이터를 함수 안에 전달할 수 있다 .매개변수는 인자라고 불리기도 한다.
function showMsg(from, text) {
alert(from + ":" + text);
}
showMsg('syong', 'hi'); // syong:hi
함수의 매개변수에 전달된 값은, 인수(argument)라고 부른다. 다시 말해 함수를 호출할 때 매개변수에 전달되는 값이다.
기본값
함수 호출 시 매개변수에 인수를 전달하지 않는 경우, 그 값은 undefined가 된다. 이때 값을 전달하지 않아도 undefined가 되지 않게 하려면 함수 선언시 =를 사용해 기본값을 설정할 수 있다.
function showMsg(from, text = "no text given") {
alert(from + ":" + text);
}
showMsg("syong"); // syong: no text given
// 아래와 같이복잡한 표현식도 기본값으로 설정할 수도 있다.
function showMsg(from, text = anotherFunction()) {
// anotherFunction()은 text가 undefined의 경우 호출되어 그 반환값이 text가 됨
}
또 다른 방법으로는, 아래와 같이 함수 선언 이후 기본값을 설정할 수 있다.
// 1. undefined인지 검사
function showMsg(text) {
// 내용
if (text == undefined) {
text = '비어있음';
}
alert(text);
}
// 2. or 연산자 사용
function showMsg(text) {
text = text || '비어있음';
alert(text);
}
// 3. nullish 연산자 사용
function showMsg(text) {
alert(text ?? '비어있음');
}
반환 값
함수 호출 시 함수를 호출한 그곳에 특정 값을 반환하게 할 수 있는데, 이를 반환 값이라고한다.
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3
return 문이 없거나 return 지시자만 있는 함수는 undefined를 반환한다.
function doNothing() {}
alert(doNothing() === undefined); // true
function doNothing() {
return;
}
alert(doNothing() === undefined); // true
함수 이름짓기
함수의 이름은 가능한 간결하고 명확해야 한다. 코드를 읽는 사람은 함수 이름만 보고도 함수가 어떤 기능을 하는지 알 수 있어야 한다.
아래와 같은 접두어를 사용하여 함수의 이름을 지을 수 있다.
- get : 값 반환
- calc : 무언갈 계산
- show : 무언갈 보여줌
- create : 무언갈 생성
- check : 무언갈 확인하여 boolean 값 반환.
또한 함수는 동작을 하나만 담당하여, 함수 이름에 언급되어 있는 동작을 수행해야 한다. 독립적인 두 개의 동작은 독립된 함수 두 개에서 나눠서 수행할 수 있어야 한다.
위의 내용을 바탕으로 이어 말해보자면, 함수가 길어지면 함수를 잘게 쪼갤 때가 되었다는 신호로 받아들여야 한다. 함수를 간결하게 만들면 테스트와 디버깅이쉬워진다. 그리고 함수 그 자체로 주석의 역할도 수행한다. 이전에 소수를 출력하는 예시가 있었다. 아래 코드를 봐보자.
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); // a prime
}
}
function isPrime(n) { // 함수명을 통해 소수 여부를 검증하는 동작을 수행한다는 것을 알 수 있음
for (let i = 2; i < n; i++) {
if ( n % i == 0) return false;
}
return true;
}
예시) pow(x,n) 함수만들기
x의 n제곱을 반환해주는 함수 pow(x, n)을 작성한다. 프롬프트 대화상자를 띄워 사용자로 부터 x와 n을 입력받고 반환값을 보여주는 코드를 작성해본다. 단, n은 1이상의 자연수여야 한다.
function pow(x, n) {
let result = x;
for (let i = 1; i < n ; i++) {
result *= x;
}
}
let x = prompt("x?", "");
let n = prompt("n?", "");
if (n < 1) {
alert(`${n}은 양의 정수이어야 합니다.`);
} else {
alert(pow(x, n));
}
함수 표현식
함수 선언 방식 이외에 함수 표현식을 사용해 함수를 만들 수 있다.
let sayHi = function() {
alert('hi');
};
alert(sayHi); // 함수 코드를 볼 수 있다.
위의 예시에서는 함수가 변수 sayHi에 저장된 값이 되었다. 이렇게 표현식을 사용하면 alert를 이용하여 함수코드를 출력할 수도 있다. 자바스크립트에서 함수는 값이다. 따라서 함수를 값처럼 취급할 수 있다.
특이한 점이 하나있다. 함수 선언문과 달리 함수 표현식의 끝에는 세미콜론이 존재한다. 이유로는 중괄호로 만든 코드 블록 끝에는 ;이 없어도 된다는 것. 함수 표현식에서는 let sayHi = ...;
와 같은 역할을 하므로 코드 블록이 아닌 값처럼 취급된다. 고로 함수 표현식에서는 세미 콜론을 붙이는 것이 좋다.
콜백 함수
매개변수가 3개 있는 함수를 작성해보겠다.함수는 반드시 질문을 해야하고, 사용자에 답변에 따라 yes()와 no()를 호출한다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "동의하셨습니다." );
}
function showCancel() {
alert( "취소 버튼을 누르셨습니다." );
}
// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);
이렇게 함수를 작성하는 것은 실무에서 아주 유용하게 쓰인다. 이때 함수 ask의 인수 showOk와 showCancle을 콜백 함수 또는 콜백이라고 칭한다. 이러한 코드를 아래와 같이 줄일 수 있다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
이렇게 이름 없이 선언한 함수를 익명함수라고 부른다. 익명함수는 변수에 할당된 것이 아니므로 ask 바깥에서는 접근할 수 없다.
함수 표현식 vs 함수 선언문
문법
- 함수 선언문에서 함수는 주요 코드 흐름 중간에 독자적인 구문 형태로 존재한다.
- 함수 표현식에서 함수는 표현식이나 구문 구성 내부에 생성된다. 그러니까 가벼운 예제에서는, 할당 표현식 우측에 생성된다.
자바스크립트 엔진이 언제 함수를 생성하는가?
- 함수 선언문은 함수 선언문이 정의되기 전에도 호출이 가능하다. 따라서, 스크립트 어디에 있느냐에 상관없이 어디서든 사용할 수 있다.
- 함수 표현식은 실제 실행 흐름이 해당 함수에 도달했을 때 함수를 생성한다. 따라서, 실행 흐름이 함수에 도달했을 때부터 해당 함수를 사용할 수 있다.
// 함수 선언문
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
// 함수 표현식
sayHi("John"); // error!
let sayHi = function(name) {
alert( `Hello, ${name}` );
};
스코프
- 엄격 모드에서 함수 선언문이 코드 블록내에 위치할 경우, 해당 함수는 블록 내 어디서든 접근할 수 있다. 하지만 블록 밖에서는 함수에 접근하지 못한다.
- 그에반해 함수 표현식에서는 호출할 수 있다.
// 함수 선언문을 사용한 경우
let age = prompt("나이를 알려주세요.", 18);
// 조건에 따라 함수를 선언함
if (age < 18) {
function welcome() {
alert("안녕!");
}
} else {
function welcome() {
alert("안녕하세요!");
}
}
welcome(); // Error: welcome is not defined
// 함수 표현식을 사용한 경우
let age = prompt("나이를 알려주세요.", 18);
let welcome;
if (age < 18) {
welcome = function() {
alert("안녕!");
};
} else {
welcome = function() {
alert("안녕하세요!");
};
}
welcome();
그래서 함수 선언문과 표현식 중 무얼 쓰라는거야?
우선 함수 선언문을 이용해 함수를 선언하는 것이 좋다. 이유로는 함수가 선언되기 전에 호출할 수 있어 코드 구성을 자유롭게 할 수 있기 때문이다. 또한, 가독성도 좋아진다. 그러나 위의 예제와 같이 조건에 따라 함수를 선언해야 하는 경우에는 함수 표현식을 사용한다.
화살표 함수 기본
화살표 함수를 활용해 함수 표현식보다 단순하고 간결한 문법을 사용할 수 있다.
// 이러한 함수 표현식을
let func = function(arg1, arg2) {
return expression;
};
// 화살표 함수로 아래와 같이 바꿀 수 있다.
let function = (arg1, arg2) => expression;
인수가 하나만 존재한다면, 인수를 감싸는 괄호를 생략할 수 있다.
let double = n => n*2;
// 위의 화살표 함수 코드와 동일하다.
let double = function(n) {
return n*2;
}
인수가 하나도 없을 때에는 괄호를 비워둔다. 이때 소괄호는 생략할 수 없다.
함수 본문이 한 줄인 간단한 함수는 화살표 함수를 사용하여 만드는 것이 편리하다.
본문이 여러 줄인 화살표 함수
평가해야 할 표현식이나 구문이 여러 개인 함수가 있는 경우, 중괄호 안에 평가해야 할 코드를 넣어준다. 그리고 return
지시자를 사용해 명시적으로 결과값을 반환해 주어야 한다.
let sum = (a, b) => {
let result = a + b;
return result;
};
'Frontend > JavaScript' 카테고리의 다른 글
[JS] 모던 JavaScript 튜토리얼#2 자바스크립트 기본 (1) | 2023.11.20 |
---|---|
[JS] 모던 JavaScript 튜토리얼#2 자바스크립트 기본 (1) | 2023.11.03 |
[JS] 모던 JavaScript 튜토리얼#2 자바스크립트 기본 (1) | 2023.10.31 |
[JS] 모던 JavaScript 튜토리얼#1 소개 (0) | 2023.10.30 |
[JS] 얕은 복사, 깊은 복사 (0) | 2023.04.16 |