본문 바로가기
Programming Language/JavaScript

5. 함수

by Ray 2021. 1. 24.

어떤 작업을 수행하기 위해 필요한 문들의 집합을 정의한 코드 블록.

이름과 매개변수를 갖으며 필요한 때에 호출하여, 코드블록에 담긴 문을 일괄 실행.

함수 정의

함수를 정의하는 방식

  • 함수 선언문
  • 함수 표현식
  • Function 생성자 함수

함수 선언문

ex)

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

함수 선언문의 경우, 함수명을 생략할 수 없다.

함수 표현식

JavaScript의 함수는 일급객체

  • 무명의 리터럴로 표현 가능
  • 변수나 자료 구조에 저장 가능
  • 함수의 파라미터로 전달 가능
  • 반환값으로 사용 가능

⇒ 이를 이용한 방식을 함수 표현식

ex)

// 함수 표현식
var square = function(number) {
return number * number;
};

익명함수 : 함수명을 생략하고 정의한 함수

ex)

// 기명 함수 표현식(named function expression)
var foo = function multiply(a, b) {
return a * b;
};

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

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

함수 호출시 함수명이 아닌 함수를 할당한 변수명을 사용해야 함

(일급객체이기에 함수를 변수에 할당 가능)

함수가 할당된 변수를 사용해 함수를 호출하지 않고 기명 함수의 함수명을 사용해 호출하게 되면 에러가 발생 → 함수 표현식에서 사용한 함수명은 외부 코드에서 접근 불가능

함수명은 재귀적 호출이나 디버거에서 함수를 구분하는 식별자의 역할

Function 생성자 함수

함수 선언문과 함수 표현식은 함수 리터럴 방식이며, 이는 Function 생성자 함수를 축약

ex)

new Function(arg1, arg2, ... argN, functionBody)

var square = new Function('number', 'return number * number');
console.log(square(10)); // 100

함수 호이스팅

함수 호이스팅 : 함수 선언의 위치와 상관없이 코드 내 어디서나 호출 가능

JavaScript는 ES6의 let, const를 포함하여 모든 선언을 호이스팅함

3가지 함수 정의 방식은 동장 방식에 차이가 있음

함수 선언문의 경우,

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

함수 선언, 초기화, 할당이 한번에 이루어져, 함수선언과 상관없이 어디서나 호출 가능

함수 호이스팅이 일어남

함수 선언문으로 함수를 정의하면 사용하기에 쉽지만 대규모 애플리케이션을 개발하는 경우 인터프리터가 너무 많은 코드를 변수 객체(VO)에 저장하므로 애플리케이션의 응답속도는 현저히 떨어질 수 있으므로 주의해야 함

함수 표현식의 경우,

함수 표현식은 함수 선언문과는 달리 스크립트 로딩 시점에 변수 객체(VO)에 함수를 할당하지 않고 runtime에 해석되고 실행.

함수 호이스팅이 아니라 변수 호이스팅이 일어남

변수 호이스팅 : 변수 생성 및 초기화와 할당이 분리되어 진행되며, 호이스팅된 변수는 underdefined로 초기화되고 실제값의 할당은 할당문에서 이루어짐.

일급 객체(First-class object)

: 생성, 대입, 연산, 인자 또는 반환값으로서의 전달 등 프로그래밍 언어의 기본적 조작을 제한없이 사용할 수 있는 대상

일급 객체의 조건

  • 무명의 리터럴로 표현 가능
  • 변수나 자료 구조에 저장
  • 함수의 매개변수에 전달 가능
  • 반환값으로 사용 가능

익명 함수를 변수에 담아 호출가능

매개 변수

함수의 작업 실행을 위해 추가적인 정보가 필요할 경우, 매개변수를 지정

Call-by-value

원시 타입 인수는 Call-by-value로 동작

함수 호출 시 원시 타입 인수를 함수에 매개변수로 전달할 때 매개변수에 값을 복사하여 함수로 전달하는 방식

Call-by-reference

객체형(참조형) 인수는 Call-by-reference로 동작

함수 호출 시 참조 타입 인수를 함수에 매개변수로 전달할 때 매개변수에 값이 복사되지 않고 객체의 참조값이 매개변수에 저장되어 함수로 전달되는 방식

함수의 다양한 형태

즉시 실행 함수 : 함수의 정의와 동시에 실행되는 함수

최초 한번만 호출되며 다시 호출할 수는 없다.

⇒ 즉시 실행 함수 내에 처리 로직을 모아 두면 혹시 있을 수도 있는 변수명 또는 함수명의 충돌을 방지 가능

ex)

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

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

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

// 따라서 즉시 실행 함수는 소괄호로 감싸준다.
(function () {
// ...
}());

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

내부 함수 : 함수 내부에 정의된 함수

자식함수는 부모함수 외부에서 접근 불가

ex)

function parent(param) {
var parentVar = param;
function child() {
var childVar = 'lee';
console.log(parentVar + ' ' + childVar); // Hello lee
}
child();
console.log(parentVar + ' ' + childVar);
// Uncaught ReferenceError: childVar is not defined
}
parent('Hello');

재귀 함수 : 자기 자신을 호출하는 함수

ex)

function fibonacci(n) {
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}

콜백 함수 : 특정 이벤트가 발생했을 때, 시스템에 의해 호출되는 함수

ex)

function doSomething() {
var name = 'Lee';

setTimeout(function () {
console.log('My name is ' + name);
}, 100);
}

doSomething(); // My name is Lee

Template Literal

ES6는 템플릿 리터럴이라는 새로운 문자열 표기법을 도입

  • 일반 문자열과 비슷해 보이지만, ‘ 또는 “ 같은 따옴표 문자 대신 백틱(backtick) 문자 `를 사용

  • 일반적인 문자열과 달리 여러 줄에 걸쳐 문자열을 작성할 수 있으며 템플릿 리터럴 내의 모든 공백은 있는 그대로 적용

    • 연산을 사용하지 않고 String Interpolation으로 새로운 문자열 삽입 가능

      String Interpolation은 ${ … }으로 표현식을 감싸며, 표현식을 문자열로 강제 타입 변환

ex)

const template = 템플릿 리터럴은 '작은따옴표(single quotes)'과 "큰따옴표(double quotes)"를 혼용할 수 있다.;

const template = `

`;

const first = 'Ung-mo';
const last = 'Lee';

// ES5: 문자열 연결
console.log('My name is ' + first + ' ' + last + '.');
// "My name is Ung-mo Lee."

// ES6: String Interpolation
console.log(My name is ${first} ${last}.);
// "My name is Ung-mo Lee."

console.log(1 + 1 = ${1 + 1}); // "1 + 1 = 2"

화살표 함수

화살표 함수의 선언

function 키워드 대신 화살표(=>)를 사용하여 보다 간략한 방법으로 함수를 선언

ex)

// 매개변수 지정 방법
() => { ... } // 매개변수가 없을 경우
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;
};

화살표 함수의 호출

화살표 함수는 익명함수로만 사용 가능

ex)

// ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100

// ES6
const pow = x => x * x;
console.log(pow(10)); // 100

콜백 함수로 사용 가능

ex)

// ES5
var arr = [1, 2, 3];
var pow = arr.map(function (x) { // 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 ]

화살표 함수의 this

화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정

화살표 함수의 this 언제나 상위 스코프의 this를 가리킴.

화살표 함수를 사용하면 안되는 경우

  • 메소드 선언

    화살표 함수내부의 this가 메소드가 호출한 객체가 아닌, 상위 컨텍스트인 전역객체를 가리킴

  • prototype

  • 생성자 함수

  • addEventListener 함수의 콜백 함수

'Programming Language > JavaScript' 카테고리의 다른 글

7. 스코프  (0) 2021.01.24
6. 객체  (0) 2021.01.24
4. 제어문  (0) 2021.01.24
3. 연산자  (0) 2021.01.24
2. 데이터 타입과 변수  (0) 2021.01.24