본문 바로가기

DEVELOPMENT/JavaScript

[JavaScript] 함수 - 함수 정의, 스코프, 함수 호이스팅, 즉시 실행 함수

함수 정의

 

1. 함수 선언문

 

*형식

function 함수명(){}

*함수 정의, 호출

// 함수 정의
function gugudan(){
	for(let i = 1; i <= 9; i++) {
    	console.log(`3 * ${i} = ${3 * i}`);
    }
}

// 함수 호출
gugudan();

 

 

2. 함수 표현식

함수는 객체에서 파생된 자료형이다. 자바스크립트에서 자료형은 변수에 할당할 수 있어야 한다. 따라서 함수도 변수에 할당할 수 있는데, 이를 이용한 함수 정의 방법을 함수 표현식이라고 한다.

함수 표현식은 변수에 할당하는 함수에 식별자가 있으면 네이밍 함수, 없으면 익명 함수로 다시 구분한다.

 

*형식

const 함수명 = function(){}; // 익명 함수
const 함수명 = function 식별자(){}; // 네이밍 함수

*함수 정의, 호출

// 함수 정의(네이밍 함수)
const gugudan = function naming(){
	for(let i = 1; i <= 9; i++) {
    	console.log(`3 * ${i} = ${3 * i}`);
    }
};

// 함수 호출
gugudan();
// 함수 정의(익명 함수)
const gugudan = function(){
	for(let i = 1; i <= 9; i++) {
    	console.log(`3 * ${i} = ${3 * i}`);
    }
};

// 함수 호출
gugudan();

 

 

3. 화살표 함수

화살표 함수는 익명 함수로만 정의할 수 있어서 함수를 호출하려면 정의된 함수를 변수에 할당하는 방법인 함수 표현식을 사용해야 한다.

 

*형식

const 함수명 = () => {};

*함수 정의, 호출

// 함수 정의
const gugudan = () => {
	for(let i = 1; i <= 9; i++) {
    	console.log(`3 * ${i} = ${3 * i}`);
    }
};

// 함수 호출
gugudan();

 

 

매개변수

 

매개변수는 함수가 호출될 때 전달받은 데이터를 할당하기 위해 함수에서 선언하는 변수로, 다음과 같은 특징이 있다.

*매개변수의 기본값은 undefined 이다.

*함수를 호출하며 데이터를 전달해도 매개변수를 정의하지 않으면 데이터를 전달받지 못한다. 단, 오류가 발생하지는 않는다.

*함수를 호출할때 전달한 데이터와 매개변수는 일대일 매칭 관계가 형성된다.

 

 

return 문

 

return 문을 사용하면 함수 내부에서 함수를 호출할 곳으로 데이터를 전달할 수 있다.

반환한 데이터를 반환값이라고 하며, 데이터를 반환하지 않으면 단순히 함수 실행을 종료하는 역할만 하게 된다. (undefined 반환)

 

*화살표 함수에서 {}를 생략하면 화살표 다음에 오는 코드는  return 문으로 처리된다.

const sum = (num1, num2) => num1 + num2;
const result = sum(10, 20); // 30

 

 

스코프(scope)

 

스코프는 변수나 함수와 같은 참조 대상 식별자를 찾아내기 위한 규칙이다.

스코프는 블록 스코프 방식과 함수 스코프 방식을 기준으로 전역 스코프와 지역 스코프로 구분한다.

 

1. 함수 스코프

함수 스코프는 함수에서 정의한 블록문만 스코프의 유효 범위로 인정하는 방식이다.

결국 함수 내부는 지역 스코프, 함수 외부는 전역 스코프 영역이 된다.

let a = 10; // 전역 스코프
function sum() {
    let b = 5; // 지역 스코프
    console.log(`함수 내부 a: ${a}`); 
    console.log(`함수 내부 b: ${b}`);
}
sum();
console.log(`함수 외부 a: ${a}`); 
console.log(`함수 외부 b: ${b}`);
함수 내부 a: 10
함수 내부 b: 5
함수 외부 a: 10
ReferenceError: b is not defined

 

 

2. 블록 스코프

블록 스코프는 {}로 구성된 블록문 기준으로 스코프의 유효 범위를 나누는 방식이다.

단, 이 방식은 let 과 const 키워드로 선언한 변수에 한해서만 적용된다.

let a = 10; // 전역 스코프
{
    let b = 5; // 지역 스코프
    console.log(`코드 블럭 내부 a: ${a}`); 
    console.log(`코드 블럭 내부 b: ${b}`); 
}
console.log(`코드 블럭 외부 a: ${a}`); 
console.log(`코드 블럭 외부 b: ${b}`);
코드 블럭 내부 a: 10
코드 블럭 내부 b: 5
코드 블럭 외부 a: 10
ReferenceError: b is not defined

블록 스코프는 오직 let, const 키워드에서만 발생하므로 같은 코드를 var 키워드로만 바꿔 실행하면 참조 오류가 발생하지 않는다. var 키워드는 함수 스코프 방식으로만 스코프를 나누기 때문에 블록 스코프가 적용되지 않는다.

 

 

3. 참조 우선순위

let, const 키워드는 같은 식별자의 중복 선언이 불가능하다. 하지만 정확하게는 같은 스코프 영역에서 중복 선언이 불가능하다고 할 수 있다.

다음 코드를 보면 let, const 키워드로 변수 a, b를 함수 외부에 선언하고, 함수 내부에도 똑같이 변수 a, b를 선언했는데 중복 선언 오류가 발생하지 않는다.

let a = 10; 
const b = 20;
function sum() {
    let a = 50;
    const b = 70;
    console.log(`함수 내부 a: ${a}`); 
    console.log(`함수 내부 b: ${b}`);
}
sum();
함수 내부 a: 50
함수 내부 b: 70

전역 스코프와 지역 스코프에 같은 식별자를 가지는 참조 대상이 있다면, 먼저 같은 지역 스코프의 식별자를 참조한다.

그리고 같은 지역 스코프에서 참조할 식별자를 찾지 못할 때만 전역 스코프에서 찾는다.

 

 

함수 호이스팅

 

호이스팅은 코드를 선언과 할당으로 나누었을 때, 선언부를 스코프 최상위로 끌어올리는 것을 말한다.

함수 선언문이나 var 키워드를 사용한 함수 표현식, 화살표 함수 방식은 전부 호이스팅의 대상이 된다.

printHello();
function printHello(){
	console.log("Hello");
}
Hello

 

 

 

즉시 실행 함수

 

즉시 실행 함수는 함수를 정의하면서 동시에 실행까지 하는 함수이다.

(function(){})();

 

즉시 실행 함수로 함수를 정의하면 전역 스코프가 오염되는 것을 방지할 수 있다.

한번 실행되고 나면 메모리에 데이터가 남아 있지 않아서, init 식별자는 한 번도 사용되지 않은 것처럼 인식된다.

(function init(){
	console.log("initialized!");
})(); // initialized!
init(); // ReferenceError: init is not defined

 

매개변수가 있는 함수도 즉시 실행 함수로 정의해서 실행할 수 있다.

(function sum(a, b){
	console.log(a + b);
})(10, 20); //30