04.함수 (function)

Updated:


1. 함수 개요

  • 함수(function)란 하나의 특별한 목적의 작업을 수행하도록 설계된 독립적인 블록을 의미합니다. 이러한 함수는 필요할 때마다 호출하여 해당 작업을 반복해서 수행할 수 있습니다.

  • 자바스크립트에서는 함수도 하나의 타입(datatype)입니다. 따라서 함수를 변수에 대입하거나, 함수에 프로퍼티를 지정하는 것도 가능합니다.

function sum(x, y) {
  return x + y;
  console.log(x);
}

sum(1, 3);

const a = sum(1, 3);
const b = sum(4, 12);

console.log(sum(1, 3)); // 4
console.log(b); // 16
console.log(a + b); // 20

// sum(1, 3) 인 1, 3 을 인수라고 함 (argument)
// sum(x, y) 는 매게 변수라고 함 (Parameter)
// 함수를 여러번 실행하는것이 효율적이지 않기 때문에 변수에 담아서 실행 되는 게 효율적임!!
// 함수 안애서 return 키를 쓰느건 그이하에 있는 코드는 실행 되지 않음

function sum(x, y) {
  if (x < 2) {
    return;
  }
  return x + y;
}

console.log(sum(7, 3)); // 10

🔹 함수 형식

🔸 함수 선언문

  • 함수 선언문(Function declaration) 방식으로 정의한 함수는 function 키워드와 이하의 내용으로 구성됩니다.

함수명 : 함수 선언문의 경우, 함수명은 생략할 수 없습니다. 함수명은 함수 몸체에서 자신을 재귀적(recursive) 호출하거나 자바스크립트 디버거가 해당 함수를 구분할 수 있는 식별자입니다.

매개변수 목록 : 0개 이상의 목록으로 괄호로 감싸고 콤마로 분리합니다. 다른 언어와의 차이점은 매개변수의 타입을 기술하지 않는다는 것입니다. 이 때문에 함수 몸체 내에서 매개변수의 타입 체크가 필요할 수 있습니다.

함수 몸체 : 함수가 호출되었을 때 실행되는 문들의 집합입니다. 중괄호({ })로 문들을 감싸고 return 문으로 결과값을 반환할 수 있습니다. 이를 반환값(return value)라 합니다

// 함수 선언문
function square(number) {
  return number * number;
}

🔸 함수 표현식

  • 함수 표현식 방식으로 정의한 함수는 함수명을 생략할 수 있다. 이러한 함수를 익명 함수(anonymous function)이라 합니다. 함수 표현식에서는 함수명을 생략하는 것이 일반적입니다.
// 기명 함수 표현식(named function expression)
let foo = function multiply(a, b) {
  return a * b;
};

// 익명 함수 표현식(anonymous function expression)
let bar = function (a, b) {
  return a * b;
};

console.log(foo(10, 5)); // 50
console.log(multiply(10, 5)); // Uncaught ReferenceError: multiply is not defined

2. 화살표 함수 (Arrow Function)

  • 화살표 함수는 function 키워드 대신 화살표(=>)를 사용하여 간략한 방법으로 함수를 선언 할 수 있습니다.

  • 하지만 모든 경우 화살표 함수를 사용할 수 있는 것은 아닙니다. 그 이유는 아래의 차이점을 확인 하시면 됩니다.

2-1 화살표 함수 선언

// 1. 매개변수 지정 방법
() => { ... }       // 매개변수가 없을 경우
x => { ... }        // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... }   // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.

// 함수 몸체 지정 방법
x => { return x * x }   // single line block
x => x * x              // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 위 표현과 동일하다.

() => { return { a: 1 }; }
() => ({ a: 1 })        // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.

() => {                 // multi line block.
  const x = 10;
  return x * x;
};

2-2 화살표 함수 호출

  • 화살표 함수는 익명 함수로만 사용할 수 있습니다. 따라서 화살표 함수를 호출하기 위해서는 함수 표현식을 사용합니다.

  • ES5 버전

let pow = function (x) {
  return x * x;
};
console.log(pow(10)); // 100
  • ES6 버전
const pow = (x) => x * x;
console.log(pow(10)); // 100

콜백 함수로 arrow function 사용하기

  • ES5 버전
let arr = [1, 2, 3];
let pow = arr.map(function (x) {
  return x * x;
});

console.log(pow);
// [ 1, 4, 9 ]
  • ES6 버전
const arr = [1, 2, 3];
const pow = arr.map((x) => x * x);

console.log(pow); // [ 1, 4, 9 ]

🔑 2-3 일반함수와 화살표 함수의 차이점

  • this

    • 일반 함수와 화살표 함수의 가장 큰 차이점은 this 입니다.

    • 화살표 함수와 일반 함수는 this가 다른 곳을 가리킵니다.

    • 화살표 함수의 this는 바로 상위 스코프의 this와 같습니다.

    • 일반 함수는 this가 동적으로 바인딩 됩니다. 일반 함수의 this는 내부 함수, 콜백 함수: 전역 객체, 객체의 메소드, 생성자 함수 입니다.

  • 생성자 함수로 사용 가능 여부

    • 일반 함수는 생성자 함수로 사용할 수 있지만, 화살표 함수는 생성자 함수로 사용할 수 없습니다.

    • 화살표 함수는 prototype 프로퍼티를 가지고 있지 않기 때문 입니다.

  • arguments 사용 가능 여부

    • 일반 함수 에서는 함수가 실행 될때 암묵적으로 arguments 변수가 전달되어 사용할 수 있습니다.

    • 화살표 함수에서는 arguments 변수가 전달되지 않습니다.


3. 즉시 실행 함수 IIFE (Immediately-Invoked Function Expression)

  • 함수의 정의와 동시에 실행되는 함수를 즉시 실행 함수(IIFE, Immediately Invoke Function Expression)라고 합니다.

  • 최초 한번만 호출되며 다시 호출할 수는 없다. 이러한 특징을 이용하여 최초 한번만 실행이 필요한 초기화 처리등에 사용할 수 있습니다.

// 기명 즉시 실행 함수(named immediately-invoked function expression)
(function myFunction() {
  let a = 3;
  let b = 5;
  return a * b;
}());

// 익명 즉시 실행 함수(immediately-invoked function expression)
(function () {
  let a = 3;
  let b = 5;
  return a * b;
}());

// SyntaxError: Unexpected token (
// 함수선언문은 자바스크립트 엔진에 의해 함수 몸체를 닫는 중괄호 뒤에 ;가 자동 추가된다.
function () {
  // ...
}(); // => };();

// 따라서 즉시 실행 함수는 소괄호로 감싸준다.
(function () {  // 첫번째 방식을 더() 가 안쪽에 있는 방식에 사용을 더 권장됨
  // ...
}());

(function () {
  // ...
})();

왜? 언제 즉시실행 함수를 사용할까?

  • 자바스크립트에서 가장 큰 문제점 중의 하나는 파일이 분리되어 있다하여도 글로벌 스코프가 하나이며 글로벌 스코프에 선언된 변수나 함수는 코드 내의 어디서든지 접근이 가능하다는 것입니다.

  • 따라서 다른 스크립트 파일 내에서 동일한 이름으로 명명된 변수나 함수가 같은 스코프 내에 존재할 경우 원치 않는 결과를 가져올 수 있습니다.

  • 즉시 실행 함수 내에 처리 로직을 모아 두면 혹시 있을 수도 있는 변수명 또는 함수명의 충돌을 방지할 수 있어 이를 위한 목적으로 즉시실행함수를 사용되기도 합니다.


4. 함수 호이스팅 (Hoisting)

  • 함수 선언문의 경우, 함수 선언의 위치와는 상관없이 코드 내 어느 곳에서든지 호출이 가능한데 이것을 함수 호이스팅(Function Hoisting)이라 합니다.

  • 자바스크립트는 ES6의 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅(Hoisting)합니다

  • 호이스팅이란 var 선언문이나 function 선언문 등 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성을 합니다

  • 즉, 자바스크립트는 모든 선언문(var, let, const, function, function*, class)이 선언되기 이전에 참조 가능합니다.

  • 함수 선언문으로 정의된 함수는 자바스크립트 엔진이 스크립트가 로딩되는 시점에 바로 초기화하고 이를 VO(variable object)에 저장.

  • 즉, 함수 선언, 초기화, 할당이 한번에 이루어집니다. 그렇기 때문에 함수 선언의 위치와는 상관없이 소스 내 어느 곳에서든지 호출이 가능합니다.

  • 함수의 내용이 복잡해 질때, 해석하기가 좋지 않기 때문에 함수의 만들어 지는 부분은 코드 하단부에 많이 사용하게 됩니다.

let res = square(5);

function square(number) {
  return number * number;
}
  • 주의!! 함수 선언문의 경우와 달리 표현식에서는 함수 호이스팅이 아니라 변수 호이스팅이 발생 합니다
let res = square(5); // TypeError: square is not a function

let square = function (number) {
  return number * number;
};

5. 타이머 함수

setTimeout(함수, 시간): 일정 시간 후 함수 실행

setInterval(함수, 시간): 시간 간격마다 함수 실행

clearTimeout(): 설정된 Timeout 함수를 종료

clearInterval(): 설정된 Interval 함수를 종료

  • 자주 사용되니 반드시 기억 해 놓자!!
// 3000ms 는 3초에 해당되는 단위
setTimeout(function () {
  console.log("Jacob");
}, 3000);

// 화살표 함수로 표현한거: 같은 값이 출력됨
setTimeout(() => {
  console.log("Jacob");
}, 3000);

// 변수로 지정하여 clearTimeout()으로 함수를 종료
const timer = setTimeout(() => {
  console.log("Jacob");
}, 3000);

const h1El = document.querySelector("h1");
h1El.addEventListener("click", () => {
  clearTimeout(timer);
});

// setInterval 지속적으로 시간이 증가 됨
const timer2 = setInterval(() => {
  console.log("Jacob");
}, 3000);

// h1 클릭하면 setInterval 작업 중지됨
const h1El2 = document.querySelector("h1");
h1El2.addEventListener("click", () => {
  clearInterval(timer);
});

🔑 6. 콜백 함수 (callback)

  • 콜백 함수(callback function)는 함수를 명시적으로 호출하는 방식이 아니라 특정 이벤트가 발생했을 때 시스템에 의해 호출되는 함수를 말합니다.

  • 처리하는데 시간이 많이 걸릴때, 콜백함수가 처리된 다음에 매개변수로 callback 함수를 실행해 주면 모든 처리 이후에 실행 가능하게 해줍니다.

  • 코드 작성시, 특정한 실행 위치를 보장해주는 방법입니다.

  • 위에 타이머 함수 도 한 종류의 콜백 함수 입니다

// 3초뒤에 timeout 되는 함수
// 이렇게 하면 Done! 이 먼저 실행하게 됨
function timeout() {
  setTimeout(() => {
    console.log("Jacob!");
  }, 3000);
}

timeout();
console.log("Done!");

// timeout (안에다가 쓰는 함수를..) -> 콜백이라고 함.

function timeout(cb) {
  setTimeout(() => {
    console.log("Jacob2!");
    cb();
  }, 3000);
}
timeout(() => {
  console.log("Done2!");
});

Reference

Leave a comment