함수와 스코프
프로그램을 작성하다 보면 특정 작업을 여러 번 수행해야 하거나, 복잡한 작업을 작은 단위로 나누어 관리해야 할 필요성을 느끼게 됩니다. 이때 등장하는 개념이 바로 함수(Function) 입니다. 함수는 특정 목적을 가진 코드 블록을 묶어 이름을 붙인 것으로, 필요할 때마다 호출하여 재사용할 수 있게 해줍니다.
또한, 프로그램의 규모가 커지면 변수나 함수의 이름이 충돌하거나, 특정 데이터에 대한 접근을 제한해야 할 필요가 생깁니다. 이때 중요한 역할을 하는 것이 스코프(Scope) 입니다. 스코프는 변수나 함수가 어디에서 접근 가능한지를 결정하는 '유효 범위'를 의미합니다.
이번 장에서는 자바스크립트에서 함수를 정의하고 사용하는 다양한 방법들을 배우고, 변수의 접근성과 생명주기를 결정하는 스코프의 원리를 함께 이해해 보겠습니다. 이 두 가지 개념은 효율적이고 안정적인 코드를 작성하는 데 필수적인 요소입니다.
함수: 코드를 묶고 재사용하는 마법
함수는 마치 자동판매기와 같습니다. 동전을 넣고(입력), 버튼을 누르면(호출), 원하는 음료가 나오는(출력) 것처럼, 함수는 특정 입력을 받아 정해진 작업을 수행하고 결과를 반환할 수 있습니다.
함수 선언하기: function
키워드
자바스크립트에서 함수를 선언하는 가장 기본적인 방법은 function
키워드를 사용하는 것입니다.
// 1. 매개변수와 반환값이 없는 함수
function sayHello() {
console.log("안녕하세요!");
}
sayHello(); // 함수 호출: "안녕하세요!" 출력
// 2. 매개변수가 있는 함수
function greet(name) { // name은 매개변수(parameter)
console.log(`안녕하세요, ${name}님!`);
}
greet("김철수"); // 함수 호출: "김철수"는 인자(argument)
greet("이영희"); // 함수 재사용: 다른 인자를 전달하여 다른 결과 생성
// 3. 반환값이 있는 함수
function add(a, b) { // a와 b는 매개변수
let sum = a + b;
return sum; // 함수의 실행 결과를 반환합니다.
}
let result = add(5, 3); // 함수 호출: 5와 3은 인자
console.log(result); // 결과: 8
console.log(add(10, 20)); // 함수 호출 결과를 직접 사용: 30
function 함수이름(매개변수1, 매개변수2, ...)
: 함수를 선언하는 키워드와 함수 이름, 그리고 괄호 안에 매개변수 목록을 작성합니다. 매개변수는 함수가 호출될 때 외부로부터 전달받을 값을 임시로 저장하는 변수입니다.{ ... }
: 중괄호 안에는 함수가 호출될 때 실행될 코드 블록을 작성합니다.return 값;
:return
키워드는 함수의 실행을 종료하고, 지정된값
을 함수를 호출한 곳으로 돌려줍니다.return
문이 없거나return
뒤에 값이 없으면undefined
가 반환됩니다.
함수 표현식: 변수에 함수 할당하기
함수는 값으로 취급될 수 있기 때문에, 변수에 할당할 수도 있습니다. 이를 함수 표현식(Function Expression) 이라고 합니다.
const multiply = function(x, y) { // 함수를 익명 함수로 선언하고 multiply 변수에 할당
return x * y;
}; // 함수 표현식 끝에는 세미콜론(;)을 붙이는 것이 일반적입니다.
console.log(multiply(4, 5)); // 결과: 20
// 변수에 할당되었으므로, 해당 변수 이름으로 호출합니다.
let calculate = multiply;
console.log(calculate(2, 7)); // 결과: 14
함수 표현식은 특히 나중에 살펴볼 콜백 함수(다른 함수의 인자로 전달되는 함수)를 다룰 때 유용하게 사용됩니다.
화살표 함수: 간결한 함수 표현
ES6(ECMAScript 2015)에서 도입된 화살표 함수 (Arrow Function)는 함수를 더 간결하게 작성할 수 있는 새로운 문법입니다. 특히 짧은 함수를 작성할 때 가독성을 높여줍니다.
// 1. 매개변수가 하나일 경우 괄호 생략 가능
const greetPerson = name => {
console.log(`안녕, ${name}!`);
};
greetPerson("수진"); // 결과: 안녕, 수진!
// 2. 매개변수가 없거나 두 개 이상일 경우 괄호 필수
const showCurrentTime = () => {
console.log(new Date().toLocaleTimeString());
};
showCurrentTime(); // 현재 시각 출력 (예: 오후 11:30:45)
const divide = (a, b) => {
return a / b;
};
console.log(divide(10, 2)); // 결과: 5
// 3. 함수 본문이 한 줄이고 `return`이 있는 경우, 중괄호와 `return` 생략 가능
const subtract = (x, y) => x - y;
console.log(subtract(10, 4)); // 결과: 6
// 객체를 반환할 때는 소괄호로 감싸야 합니다.
const createUser = (id, name) => ({ id: id, name: name });
console.log(createUser(1, "지훈")); // 결과: { id: 1, name: '지훈' }
화살표 함수는 문법적인 간결함 외에도 this
바인딩 방식에서 일반 함수와 차이가 있지만, 이 부분은 뒤이어 더 심화된 주제를 다룰 때 상세히 설명하겠습니다. 지금은 주로 간결한 함수를 정의할 때 사용한다는 점을 기억하시면 좋습니다.
매개변수 기본값 (Default Parameters)
ES6부터는 함수를 호출할 때 매개변수가 전달되지 않으면 사용할 기본값을 지정할 수 있습니다.
function welcome(name = "손님") { // name 매개변수의 기본값을 "손님"으로 설정
console.log(`환영합니다, ${name}님!`);
}
welcome("민준"); // 결과: 환영합니다, 민준님!
welcome(); // 결과: 환영합니다, 손님님! (매개변수를 전달하지 않아 기본값이 사용됨)
나머지 매개변수 (Rest Parameters)
함수에 전달된 인자들을 배열 형태로 받을 수 있게 해주는 문법입니다. 매개변수 이름 앞에 ...
을 붙입니다.
function sumAll(...numbers) { // numbers는 배열이 됩니다.
let total = 0;
for (let number of numbers) { // for...of 반복문은 배열의 요소를 순회할 때 유용합니다.
total += number;
}
return total;
}
console.log(sumAll(1, 2, 3)); // 결과: 6
console.log(sumAll(10, 20, 30, 40)); // 결과: 100
console.log(sumAll()); // 결과: 0
스코프: 변수의 유효 범위
스코프는 "어떤 변수가 어디에서 접근 가능한지"를 정의하는 규칙입니다. 코드를 작성할 때 변수가 어디서 선언되었는지에 따라 해당 변수에 접근할 수 있는 범위가 달라지며, 이는 프로그램의 안정성과 예측 가능성에 매우 중요한 영향을 미칩니다. 자바스크립트의 스코프는 크게 두 가지로 나눌 수 있습니다.
전역 스코프 (Global Scope)
전역 스코프는 코드의 최상단, 즉 함수나 블록({}
) 내부에 선언되지 않은 변수들이 가지는 스코프입니다. 전역 스코프에 선언된 변수는 프로그램의 어느 곳에서든 접근할 수 있습니다.
let globalVar = "나는 전역 변수입니다."; // 전역 변수 선언
function accessGlobal() {
console.log(globalVar); // 함수 내부에서 전역 변수에 접근 가능
}
accessGlobal(); // 결과: 나는 전역 변수입니다.
console.log(globalVar); // 전역에서 접근 가능: 나는 전역 변수입니다.
전역 변수를 너무 많이 사용하면 코드의 예측 가능성이 떨어지고, 다른 코드와의 이름 충돌이 발생할 위험이 커집니다. 따라서 꼭 필요한 경우가 아니라면 전역 변수 사용은 지양하는 것이 좋습니다.
지역 스코프 (Local Scope)
지역 스코프는 특정 코드 블록 내에서만 유효한 스코프를 의미합니다. 자바스크립트에서는 주로 함수 스코프와 블록 스코프가 있습니다.
-
함수 스코프 (Function Scope):
var
키워드로 선언된 변수는 해당 변수가 선언된 함수 내부에서만 유효합니다. 함수 외부에서는 접근할 수 없습니다.function createLocalVar() { var localVar = "나는 함수 스코프 변수입니다."; console.log(localVar); } createLocalVar(); // 결과: 나는 함수 스코프 변수입니다. // console.log(localVar); // ReferenceError: localVar is not defined // 함수 외부에서는 localVar에 접근할 수 없습니다.
-
블록 스코프 (Block Scope):
let
과const
키워드로 선언된 변수는{}
(중괄호)로 묶인 코드 블록 내에서만 유효합니다.if
문,for
문, 또는 단순한 코드 블록 등 모든 중괄호 영역이 블록 스코프를 형성합니다.if (true) { let blockVar = "나는 블록 스코프 변수입니다."; const BLOCK_CONST = 123; console.log(blockVar); // 결과: 나는 블록 스코프 변수입니다. console.log(BLOCK_CONST); // 결과: 123 } // console.log(blockVar); // ReferenceError: blockVar is not defined // console.log(BLOCK_CONST); // ReferenceError: BLOCK_CONST is not defined // 블록 외부에서는 접근할 수 없습니다.
var
, let
, const
의 스코프 차이점 요약:
var
: 함수 스코프. 함수 내에서 선언되면 함수 전체에서 유효. 함수 밖에서 선언되면 전역에서 유효.let
,const
: 블록 스코프.{}
블록 내에서 선언되면 해당 블록 내에서만 유효. 블록 밖에서 선언되면 전역에서 유효.
스코프 체인 (Scope Chain)
자바스크립트에서 어떤 변수에 접근하려고 할 때, 현재 스코프에서 변수를 찾고, 없으면 바깥 스코프로 이동하여 찾습니다. 이 과정이 계속되어 전역 스코프까지 올라가는 것을 스코프 체인이라고 합니다.
let globalValue = "전역 값";
function outerFunction() {
let outerValue = "외부 함수 값";
function innerFunction() {
let innerValue = "내부 함수 값";
console.log(innerValue); // "내부 함수 값" (현재 스코프)
console.log(outerValue); // "외부 함수 값" (상위 스코프)
console.log(globalValue); // "전역 값" (최상위 스코프)
}
innerFunction();
// console.log(innerValue); // ReferenceError: innerValue is not defined (innerFunction 내부 변수는 밖에서 접근 불가)
}
outerFunction();
// console.log(outerValue); // ReferenceError: outerValue is not defined (outerFunction 내부 변수는 밖에서 접근 불가)
이처럼 스코프는 변수의 생명주기와 접근 범위를 결정하며, 이는 프로그램의 오류를 줄이고 유지보수를 용이하게 하는 데 매우 중요한 개념입니다.
마무리하며
이번 장에서는 자바스크립트 코드의 핵심 구성 요소인 함수와 스코프에 대해 심도 있게 다루었습니다. 함수를 사용하여 반복되는 코드를 모듈화하고 재사용하는 방법을 익혔으며, function
키워드, 함수 표현식, 그리고 간결한 화살표 함수까지 다양한 함수의 형태를 살펴보았습니다.
또한, 변수가 어디에서 유효한지를 결정하는 스코프의 개념을 이해하고, var
, let
, const
키워드의 스코프 차이점을 명확히 파악했습니다. 스코프를 올바르게 이해하고 활용하는 것은 예상치 못한 버그를 줄이고, 코드를 더욱 견고하게 만드는 데 필수적입니다.
이제 여러분은 자바스크립트의 기본적인 흐름 제어와 코드 재사용 방법을 익혔습니다. 다음 장에서는 객체와 배열이라는 더 복잡한 데이터 구조를 다루는 방법에 대해 학습하게 될 것입니다. 배운 개념들을 바탕으로 자신만의 작은 함수들을 만들어보고, 스코프의 규칙을 적용해보는 연습을 꾸준히 해보시길 권합니다.