[모던 자바스크립트 튜토리얼] 2.15 함수

개발견 배도르만·2023년 3월 2일
0
post-thumbnail

함수

함수(function)는 유사한 동작을 하는 코드가 여러 곳에서 필요할 때 중복 없이 호출하기 위해 존재하는 자바스크립트의 프로그램의 주요 구성 요소이다.

alert() 등의 내장 함수가 있고, 직접 만들어서 사용할 수도 있다.

함수 선언

함수 선언(function declaration) 방식을 이용하면 함수를 만들 수 있다. 함수 선언문이라고 부르기도 한다.

function showMessage() {
  alert( '안녕하세요!' );
}

function 키워드, 함수 이름, 소괄호 안의 매개변수와 중괄호 안의 본문(실행할 코드)으로 구성되어 있다. 아래는 여러 매개변수를 가지는 함수 선언의 예이다.

function name(parameter1, parameter2, ... parameterN) {
  // 함수 본문
}

함수는 함수 이름 옆에 괄호를 붙여 호출한다.

function showMessage() { // 선언
  alert( '안녕하세요!' );
}

showMessage(); // 호출
showMessage(); // 호출

지역 변수

지역 변수(Local Variable)는 함수 내부에서 선언한 변수이며 함수 내에서만 접근할 수 있다.

function showMessage() {
  let message = "안녕하세요!"; // 지역 변수

  alert( message );
}

showMessage(); // 안녕하세요!

alert( message ); // ReferenceError: message is not defined (message는 함수 내 지역 변수이기 때문에 에러 발생)

전역 변수

전역 변수(Global Variable)는 함수 외부에서 선언한 변수이며 함수 내부와 외부에서 접근 및 수정이 가능한 변수이다. 외부 변수(Outer Variable)라고도 한다.


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이 출력

전역변수가 유용한 경우도 있긴 하지만 대부분의 상황에서 변수는 최대한 사용되는 함수 내에 작성하고 전역변수를 최소화하는 것이 좋다.

매개변수

매개변수(parameter)함수에서 사용될 데이터를 전달받기 위해 지정된 변수이다. 일반적으로 인자(argument)와 같은 의미로 사용되기도 하지만 엄밀히 말하면 매개변수는 함수를 정의하는 부분에서 값을 전달받는 변수이고 인자는 함수를 호출할 때 전달하는 값이라고 한다.
매개변수로 전달받은 값은 변경 가능하지만, 값을 복사해서 사용하기 때문에 원본은 변경되지 않는다. 함수 내에서만 변수의 값이 변경된다는 것이다.

function showMessage(from, text) {

  from = '*' + from + '*'; // "from"을 좀 더 멋지게 꾸며줍니다.

  alert( from + ': ' + text );
}

let from = "Ann";

showMessage(from, "Hello"); // *Ann*: Hello

// 함수는 복사된 값을 사용하기 때문에 바깥의 "from"은 값이 변경되지 않습니다.
alert( from ); // Ann

기본값

함수 호출 시 매개변수에 인자를 전달하지 않으면 그 값은 undefined가 된다.
기본값(default value)을 특정하고 싶다면 =를 사용할 수 있다.

function showMessage1(from, text = "no text given") {
  alert( from + ": " + text );
}

showMessage("Ann"); // Ann: no text given

function showMessage2(from, text = anotherFunction()) {
  // anotherFunction()은 text값이 없을 때만 호출됨
  // anotherFunction()의 반환 값이 text의 값이 됨
}

기본값을 평가하는 시점은 함수 호출 시마다, 매개변수가 없을 경우이다.

한 편으로, 기본값 관련 구문이 없는 오래된 스크립트에서는 조건문으로 동일한 기능을 대체한다.

function showMessage(from, text) {
  if (text === undefined) {
    text = 'no text given';
  }

  alert( from + ": " + text );
}

논리 연산자 || 또는 모던 js 엔진이 지원하는 nullish 병합 연산자(??)를 사용할 수도 있다.

function showMessage(from, text) {
  // text의 값이 falsy면 기본값이 할당됨
  // 이 방식은 text == ""일 경우, text에 값이 전달되지 않은것과 같다고 간주합니다..
  text = text || 'no text given';
  ...
}
  
// 매개변수 'count'가 `undefined` 또는 `null`이면 'unknown'을 출력해주는 함수
function showCount(count) {
  alert(count ?? "unknown");
}

showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown

반환 값

함수를 호출한 곳에 특정 값을 반환할 수 있다. 이 때 반환하는 값을 반환 값(return value)이라고 한다.
'return' 지시자를 사용한다.

function sum(a, b) {
  return a + b;
}

let result = sum(1, 2);
alert( result ); // 3

return은 함수 내에서 여러 번 사용할 수도 있고, 조건에 따라 사용할 수도 있다. 또한 return 뒤에 아무 값도 없다면 undefined를 반환하면서 함수를 즉시 종료한다.

주의할 점은 return 뒤에 세미콜론(;)이 없으면 js엔진에서 자동으로 세미콜론을 삽입하기 때문에 신중하게 개행해야 한다.

return //undefined가 리턴되면서 함수 종료. 따라서 아래의 코드는 실행되지 않음
 (some + long + expression + or + whatever * f(a) + f(b))

함수 이름짓기

함수는 특정 동작을 수행하기 위한 코드의 모음이다. 따라서 함수의 이름은 대개 동사이다. 또한 최대한 간결하고 명확해야 한다. 함수의 동작과 기능을 함수명을 통해 유추할 수 있어야 한다.

관습적으로는 함수의 동작을 축약해서 설명하는 동사를 접두어로 붙여 함수 이름을 만든다. 추가적으로 팀 내에서도 합의가 이루어져야 한다.

  • 'show...' : 무언가를 보여줌
  • 'get...' : 값을 반환함
  • 'calc...' : 무언가를 계산함
  • 'create...' : 무언가를 생성함
  • 'check...' : 무언가를 확인하고 불린값을 반환함

예시

showMessage(..)     // 메시지를 보여줌
getAge(..)          // 나이를 나타내는 값을 얻고 그 값을 반환함
calcSum(..)         // 합계를 계산하고 그 결과를 반환함
createForm(..)      // form을 생성하고 만들어진 form을 반환함
checkPermission(..) // 승인 여부를 확인하고 true나 false를 반환함

함수는 함수 이름에 언급되어 있는 동작 하나만을 수행하는 것이 좋다. 두 가지 이상의 동작을 처리해야 한다면, 두 개의 함수로 나누는 것이 좋다.
이러한 방식으로 사용하면 함수명 자체가 주석의 역할도 수행한다고 볼 수 있다.

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;
}

✍ 정리

  • 함수는 비슷한 기능을 여러 번 호출하여 사용할 수 있게 함
  • 함수 선언 방식으로 함수를 만들 수 있음
  • 함수에 전달된 매개변수는 복사되어 함수의 지역변수가 됨
  • 함수는 전역변수에 접근할 수 있지만, 외부에서 지역변수로는 불가
  • 함수는 값을 반환할 수 있음
  • 깔끔한 코드를 위해 권장되는 몇 가지 방법이 있음
    • 전역변수보다는 지역변수 사용
    • 함수명 잘 짓기(동사, 명확성, 목적성, 간결성, 합의성)
profile
네 발 개발 개

0개의 댓글