카테고리 없음

[JS] - Function 함수

서근 2023. 1. 20. 19:48
반응형

함수

함수는 프로그램을 구성하는 주요 구성요소

지역 / 전역 변수

  • 함수 내에서 선언한 변수는 지역변수 함수 안에서만 접근 가능 하다.
  • 함수 밖에서 선언한 변수는 전역변수 라고 한다.
  • 외부 변수는 지역 변수가 없는 경우에만 사용 가능하다.
    • 함수 내부에 외부 변수와 동일한 이름을 가진 변수가 선언되어 있다면, 내부 변수는 외부변수를 무시한다.

매개변수

           // 인자(매개변수): from, text
function showMessage(from, text) { 
  alert(from + ': ' + text);
}

showMessage('Ann', 'Hello!'); // Ann: Hello!
showMessage('Ann', "What's up?"); // Ann: What's up?

함수의 매개변수에 전달된 값을 인수(argument)라고 부르기도 한다.

  • 매개변수는 함수 선언 방식 괄호 사이에 있는 변수(선언 시 쓰이는 용어).
  • 인수는 함수를 호출할 때 매개변수에 전달되는 값(호출 시 쓰이는 용어).

즉, 함수 선언 시 매개변수를 나열하게 되고, 함수를 호출할 땐 인수를 전달해 호출한다. 위 예에서 함수 showMessagefromtext라는 두 매개변수를 사용해 선언되었고, 그 후 호출 시엔 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의 인수, showOkshowCancel은 콜백 함수 또는 콜백이라고 불린다.

 

함수를 함수의 인수로 전달하고, 필요하다면 인수로 전달한 그 함수를 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 메서드를 보편적으로 사용한다.


읽어주셔서 감사합니다🤟