프론트엔드/Javascript

JS - 함수 정의 / 매개변수와 인수 / return문 / 스코프

두개의 문 2023. 8. 14. 23:13

◉ 함수란

 

▪︎ 어떤 목적을 가지고 작성한 코드를 모아 둔 블록문

 


◉ 함수 정의하는 방법 

▪︎ 자바스크립트에서는 함수 선언문, 함수 표현식, 화살표 함수 등을 사용해 정의함 

 

1. 함수 선언문으로 함수 정의하기 

▪︎ function 키워드로 함수를 정의하는 방법 

 - 식별자 = 함수명 

function 식별자(){
	// 함수 호출 시, 실행할 코드 
}
function gugudan(){
	for(let i = 1; i <= 9; i++ ){
    	console.log(`3 * ${i} = ${3 * i}`);
    }
}

 

 

▪︎ 함수 호출 방법 

함수명();

 

 

 

2. 함수 표현식으로 함수 정의하기 

▪︎ 함수는 객체에서 파생된 자료형 

  - 자료형은 변수에 할당할 수 있어야 함 

     따라서, 함수도 변수에 할당할 수 있어야 하는데 , 이를 이용한 함수 정의 방법을 '함수 표현식'이라고 함 

 

▪︎ 함수 표현식은 변수에 할당하는 함수에

  식별자가 있으면, 네이밍 함수(naming function)

                 없으면, 익명 함수(anonymous function)                           

 

▪︎ 단, 함수 호출 시 함수 선언문에서 function 키워드 다음에 오는 식별자로 함수를 호출하지 않고, 할당한 변수명으로 함수 호출함 

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

gugudan();	// 함수 호출

 

▪︎ function 키워드 다음에 식별자가 없는 익명 함수의 호출의 경우에도 문제 없음 

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

gugudan();	// 함수 호출 문제 없음

 

※ 함수 표현식으로 함수 정의 시, 네이밍 함수로 정의하는 것을 권장. 

   또한, 네이밍 함수의 식별자를 변수명과 동일하게 만들면, 이름을 두 번 생각하지 않아도 되고 호출할 때 헷갈리지 않아서 좋다. 

 

 

 

3. 화살표 함수로 함수 정의하기 

▪︎ ES6에서 추가된 함수 정의 방법으로, 화살표를 사용해 함수를 정의 

() => {};

 

▪︎ 화살표 함수는 익명 함수로만 정의 가능 

  → 함수 호출하려면, 정의된 함수를 변수에 할당하는 방법인 함수 표현식을 사용해야 함 

// 화살표 함수로 함수 선언 
const gugudan = () => {
	for(let i = 1; i <= 9; i++ ){
    	console.log(`3 * ${i} = ${3 * i}`);
    }
}

gugudan();	// 함수 호출

 

 


정리해보면 아래와 같다 

 

// 함수 선언문 
function 식별자() {};

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

// 화살표 함수 
() => {};

 

 


◉ 함수 기능 확장하기 

 

1. 매개변수(parameter)와 인수(argument)

 

▪︎ 매개변수 

  - 함수를 정의할 때 외부에서 전달하는 데이터를 함수에서 받을 수 있도록 정의하는 변수 

  - 매개변수의 개수 제한 없고, 쉼표로 구분해 나열함  

▪︎ 인수 

  - 정의한 함수를 호출할 때, 소괄호 안에 전달하고 싶은 데이터를 의미 

  - 즉, 함수 호출 시 전달하는 데이터로 함수의 매개변수에 자동으로 할당됨 

 

 

▪︎ 화살표 함수에서 매개변수 정의 

const sum = (num1, num2) => {
	console.log(num1, num2);
};

sum(10, 20);

 

 - 단, 화살표 함수는 매개변수가 1개일 경우, 괄호() 생략 가능 

const sum = num1 => {
	console.log(num1);
};

sum(10);

 

 

 

2. return 문 

▪︎ 함수 외부로 데이터를 반환할 때 사용 

return 식( 또는 값)

 

▪︎ 다음은 두 매개변수의 합을 구하는 함수 

function sum(num1, num2){
	let result = num1 + num2;
    console.log(result);
}

// 함수 호출 
sum(10, 20);

 

- 만약 위의 코드를 아래와 같이 바꿀 경우, 에러 발생 

function sum(num1, num2){
	let result = num1 + num2;
}

// 함수 호출 
sum(10, 20);
console.log(result);    // ReferenceError : result is not defined

 • 오류 메시지 : 정의되지 않은 변수라고 나옴 

   → 함수 외부에서 함수 내부의 변수를 참조하려고 해서 발생한 오류 

 

 • 오류가 나지 않게 하기 위해서는 return문을 이용해 함수 내부 데이터를 함수 외부로 전달해주어 함 

   → 단, 이렇게 반환된 데이터를 외부에서 사용하려면, 함수 호출 부분에서 반환값을 다시 변수에 할당해야 함 

function sum(num1, num2){
    let result = num1 + num2;
    return result;
}

// 함수 호출 
const result = sum(10, 20);
console.log(result);

 

▪︎ return문에 데이터를 반환하지 않으면, 단순히 함수 실행을 종료시키는 역할만 하게 됨 

 

 


◉ 함수의 특징 이해하기 

 

1. 스코프 

▪︎ 위의 return문에서 함수 외부에서 함수 내부의 변수를 참조하려다가 오류가 발생했었음 

  → 함수 내부의 변수를 함수 외부에서 참조할 수 없는 이유가 무엇일까? 

       '스코프' 개념에 대해 알아보자.

 

▪︎ 스코프 

  - 변수나 함수와 같은 참조 대상 식별자를 찾아내기 위한 규칙 

  - 자바스크립트는 기본으로 스코프에 따라 참조하려는 식별자를 찾음 

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

 

 

① 함수 스코프 

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

    → 함수 내부 : 지역 스코프 

        함수 외부 : 전역 스코프 

 

  - 전역 스코프의 경우, 스코프와 상관없이 모두 참조 가능 

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

 

  - 이와 달리, 다음 코드에서 함수 내부에 선언한 변수 a는 지역 스코프에 해당 

    → 함수 내부가 아닌 함수 외부에서 변수 a를 참조하려고 하면 오류 발생 

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

 

 

② 블록 스코프 

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

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

 

  - 다음은 블록 스코프 외부에 let 키워드로 변수 a를 선언하고, 블록 스코프 내부에 let 키워드로 변수 b를 선언한 뒤, 블록 스코프 내부와 외부에서 각각 참조하는 예제 

let a = 10;

{
    let b = 20;
    console.log(`코드 블록 내부 a: ${a}`);
    console.log(`코드 블록 내부 b: ${b}`);
}
console.log(`코드 블록 외부 a: ${a}`);
console.log(`코드 블록 외부 b: ${b}`);
코드 블록 내부 a: 10
코드 블록 내부 b: 20
코드 블록 외부 a: 10
ReferenceError: b is not defined

  • 변수 a : 전역 스코프여서 블록문 내부나 외부에서 전부 참조 가능 

  • 변수 b : 블록문 내부에 선언한 지역 스코프여서 블록문 내부에서는 참조 가능, 외부에서는 참조 오류 발생 

 

 ※ 블록 스코프의 경우, 오직 let, const 키워드에서만 발생 

    같은 코드를 var 키워드로만 바꿔 실행하면 참조 오류 발생하지 않음 

 

 

▪︎ 참조 우선순위

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

    먼저 같은 지역 스코프의 식별자를 참조함