[JS] - Function 함수
함수
함수는 프로그램을 구성하는 주요 구성요소
지역 / 전역 변수
- 함수 내에서 선언한 변수는
지역변수
함수 안에서만 접근 가능 하다. - 함수 밖에서 선언한 변수는
전역변수
라고 한다. - 외부 변수는 지역 변수가 없는 경우에만 사용 가능하다.
- 함수 내부에 외부 변수와 동일한 이름을 가진 변수가 선언되어 있다면, 내부 변수는 외부변수를 무시한다.
매개변수
// 인자(매개변수): from, text
function showMessage(from, text) {
alert(from + ': ' + text);
}
showMessage('Ann', 'Hello!'); // Ann: Hello!
showMessage('Ann', "What's up?"); // Ann: What's up?
함수의 매개변수에 전달된 값을 인수(argument)
라고 부르기도 한다.
- 매개변수는 함수 선언 방식 괄호 사이에 있는 변수(선언 시 쓰이는 용어).
- 인수는 함수를 호출할 때 매개변수에 전달되는 값(호출 시 쓰이는 용어).
즉, 함수 선언 시 매개변수를 나열하게 되고, 함수를 호출할 땐 인수를 전달해 호출한다. 위 예에서 함수 showMessage
는 from
과 text
라는 두 매개변수를 사용해 선언되었고, 그 후 호출 시엔 from
, Hello
라는 두 인수를 사용해 호출되었다.
// 매개변수 'count'가 `undefined` 또는 `null`이면 'unknown'을 출력해주는 함수
function showCount(count) {
alert(count ?? "unknown");
}
showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown
반환값
return value
라고 부름
- return은 함수 내 어디에서든 사용 가능하다.
- return을 만나면 함수는 즉시 실행을 중지하고 함수를 호출한 곳에 값을 반환.
- return과 반환하려는 값 사이에 새 줄을 넣으면 안 된다.
function checkAge(age) {
if (age >= 18) {
return true;
} else {
return confirm('보호자의 동의를 받으셨나요?');
}
}
let age = prompt('나이를 알려주세요', 18);
if ( checkAge(age) ) {
alert( '접속 허용' );
} else {
alert( '접속 차단' );
}
함수 이름 짓기
코드를 읽는 사람은 함수 이름만 보고도 함수가 어떤 기능을 하는지 힌트를 얻을 수 있어야 한다.
함수가 어떤 동작을 하는지 축약해서 설명해 주는 동사를 접두어로 붙여 함수 이름을 만드는 게 관습이다. 다만, 팀 내에서 그 뜻이 반드시 합의된 접두어만 사용해야 한다.
"show"
로 시작하는 함수는 대개 무언가를 보여주는 함수. 이 외에 아래와 같은 접두어를 사용할 수 있다.
"get…"
– 값을 반환함"calc…"
– 무언가를 계산함"create…"
– 무언가를 생성함"check…"
– 무언가를 확인하고 불린 값을 반환함
showMessage(..) // 메시지를 보여줌
getAge(..) // 나이를 나타내는 값을 얻고 그 값을 반환함
calcSum(..) // 합계를 계산하고 그 결과를 반환함
createForm(..) // form을 생성하고 만들어진 form을 반환함
checkPermission(..) // 승인 여부를 확인하고 true나 false를 반환함
요약
- 함수에 전달된 매개변수는 복사된 후 함수의 지역변수가 된다.
- 함수는 외부 변수에 접근할 수 있다. 하지만 함수 바깥에서 함수 내부의 지역변수에 접근하는 건 불가능.
- 함수는 값을 반환할 수 있다. 값을 반환하지 않는 경우는 반환 값이
undefined
가 된다.
함수 이름을 지을 땐 아래와 같은 규칙을 따르는 것이 좋다.
- 함수 이름은 함수가 어떤 동작을 하는지 설명할 수 있어야 합니다. 이렇게 이름을 지으면 함수 호출 코드만 보아도 해당 함수가 무엇을 하고 어떤 값을 반환할지 바로 알 수 있습니다.
- 함수는 동작을 수행하기 때문에 이름이 주로 동사입니다.
create…
,show…
,get…
,check…
등의 잘 알려진 접두어를 사용해 이름을 지을 수 있습니다. 접두어를 사용하면 함수 이름만 보고도 해당 함수가 어떤 동작을 하는지 파악할 수 있습니다.
함수 표현식
변수를 복사해 다른 변수에 할당하는 것처럼 함수를 복사해 다른 변수에 할당할 수 도 있다.
function sayHi() { // (1) 함수 생성
alert( "Hello" );
}
let func = sayHi; // (2) 함수 복사
func(); // Hello // (3) 복사한 함수를 실행(정상적으로 실행됩니다)!
sayHi(); // Hello // 본래 함수도 정상적으로 실행됩니다.
콜백 함수
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
와 showCancel
은 콜백 함수 또는 콜백이라고 불린다.
함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 그 함수를 called back 하는 것이 콜백 함수의 개념.
"yes"라고 대답한 경우 showOk
가 콜백이 되고, "no"라고 대답한 경우 showCancel
가 콜백이 된다.
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
나머지 매개변수와 스프레드 문법
상당수의 자바스크립트 내장 함수는 인수의 개수에 제약을 두지 않는다.
Math.max(arg1, arg2, ..., argN)
– 인수 중 가장 큰 수를 반환 한다.Object.assign(dest, src1, ..., srcN)
–src1..N
의 프로퍼티를dest
로 복사.
const target = { a: 1, b: 2}
const source = { c: 3, d: 4}
const returnedTarget = Object.assign(target, source);
console.log(target)
//{ a: 1, b: 2, c: 3, d: 4 }
console.log(source)
//{ c: 3, d: 4 }
console.log(returnedTarget)
//{ a: 1, b: 2, c: 3, d: 4 }
나머지 매개 변수
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 showName(firstName, lastName, ...titles) {
alert( firstName + ' ' + lastName ); // 선중 김
// 나머지 인수들은 배열 titles의 요소가 됩니다.
// titles = ["소피아", "포뇨"]
alert( titles[0] ); // 소피아
alert( titles[1] ); // 포뇨
alert( titles.length ); // 2
}
showName("선중", "김", "소피아", "포뇨");
위 예제에서 매개변수의 마지막 부분에 …
를 사용하면 처음 두 인수는 변수에, 나머지 인수들은 titles라는 [ 배열 ]에 할당되며, 호출할 때도 배열을 호출하듯이 하면 된다.
나머지 매개변수는 항상 마지막에 있어야 하는 것을 주의해야 한다.
나머지 매개변수는 남아있는 인수를 [ 배열로 ] 모으는 역할을 하므로 아래와 같이 사용하면 안 된다.
function someFunc(hi, ...my, name) {
//ERROR
}
스프레드 문법
위 함수의 파라미터 매개변수 안에서 … 은 인자값을 배열로 만들어주고 합치는 기능을 했다면, 반대로 변수로 할당된 배열을 하나하나 빼주는 역할을 해줄 수 있다.
예로 들어 Math.max
로 가장 큰 정수값을 구해보면
console.log(Math.max(1,3,5,6)) //6
아래처럼 사용할 수 있는데, 만약 배열이 들어있는 변수에서 최댓값을 구하고자 아래와 같이 사용하면 NaN 즉, 숫자가 아니다라고 반환한다.
let arr = [1,3,5,6]
console.log(Math.max(arr)) // NaN
이때 사용할 수 있는 것이 스레드문법 …
이다.
나머지 매개변수와 비슷하지만, 스레드 문법은 그것과 반대대는 역할을 한다.
함수를 호출할 때 스레드 문법을 사용하면 배열에 있는 값을 하나하나 빼와서 결국 배열 안에는 [ ]
하나도 남지 않게 된다. 즉, 아래에선 arr이 인수 목록으로 ‘확장’ 되는 것이다.
let arr = [1,3,5,6]
console.log(Math.max(...arr)) //6
console.log(...arr); //1 3 5 6
아래처럼 이터러블 객체 여러 개를 전달하는 것도 가능
여기서 이터러블은 반복가능한 객체를 뜻하며, 배열 역시 이터러블 이다.
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 순서로 합쳐집니다.)
좀 더 직관적으로 보자면 이렇다.
let seogun = '서근개발노트';
console.log([...seogun]); //[ '서', '근', '개', '발', '노', '트' ]
메서드 Array.from
은 이 트러블 객체인 문자열을 [배열]로 바꿔주기에 같은 작업을 할 수 있다.
let seogun = '서근';
console.log(Array.from(seogun)); // [ '서', '근' ]
[…seogun]
과 동일하지만 미묘한 차이가 있다.
Array.from
메서드는 유사 배열 객체와 이터러블 객체 둘 다 사용가능- 스프레드 문법은 이터러블 객체에만 사용 가능.
- 이런 이유로 무언가를 배열로 바꿀 때, 스프레드 보다
Array.from
메서드를 보편적으로 사용한다.
읽어주셔서 감사합니다🤟