자바스크립트의 함수와 실행 컨텍스트: 핵심 개념들
자바스크립트에서 함수는 매우 중요한 개념이다. 함수는 코드의 재사용성을 높이고, 복잡한 작업을 단순하게 처리할 수 있도록 도와준다. 자바스크립트는 고유의 실행 방식과 스코프 개념을 가지고 있어서, 함수의 동작을 제대로 이해하는 것이 매우 중요하다. 이번 포스트에서는 함수의 개념에서부터 실행 컨텍스트, 스코프, 클로저까지 핵심적인 자바스크립트 개념들을 통합적으로 설명하겠다.
함수란 무엇일까?
함수는 특정 작업을 수행하거나 값을 계산하는 코드의 모음이다. 자바스크립트에서는 함수가 **일급 객체(First-Class Object)**로 취급되기 때문에, 값처럼 다룰 수 있다. 즉, 함수를 변수에 할당하거나, 다른 함수의 인자로 전달하거나, 함수에서 반환할 수 있다. 이러한 일급 함수(First-Class Function)의 특성 덕분에 자바스크립트는 매우 유연한 프로그래밍을 가능하게 한다.
잘 만들어진 함수의 기준
- 하나의 역할만 수행한다. 하나의 함수가 너무 많은 작업을 하지 않도록 분리한다.
- 매개변수 개수가 적다. 매개변수가 많을수록 함수의 복잡성이 증가하므로 가능한 적게 유지한다.
- 부작용이 적다. 함수가 외부 상태를 변경하지 않거나 변경을 최소화하도록 설계한다.
함수 선언문과 화살표 함수의 차이
자바스크립트에서는 함수 선언문과 화살표 함수(Arrow Function)를 사용할 수 있는데, 이 둘은 몇 가지 중요한 차이가 있다.
- 함수 선언문은 호이스팅이 되어, 함수 선언부가 코드의 상단으로 끌어올려진다. 즉, 선언 전에 함수를 호출해도 문제가 발생하지 않는다.
- 화살표 함수는 호이스팅되지 않으며, 선언된 이후에만 호출할 수 있다. 또한, 화살표 함수는 **this**의 바인딩 방식에서 중요한 차이를 보인다.
함수 선언문
function sayHello() {
console.log("Hello!");
}
화살표 함수
const sayHello = () => {
console.log("Hello!");
};
this의 역할과 바인딩 방식
자바스크립트에서 this는 함수가 호출되는 문맥(컨텍스트)을 참조하는 키워드이다. this가 참조하는 객체는 함수가 어떻게 호출되었는지에 따라 달라진다.
- 일반 함수: 호출되는 객체에 따라 this가 결정된다.
- 화살표 함수: this는 렉시컬(lexical) 스코프에 의해 결정된다. 즉, 화살표 함수는 자신이 정의된 스코프의 this를 상속받는다. 이를 통해 this의 바인딩을 고정할 수 있다.
this를 바인딩하는 방법
- 암시적 바인딩: 함수가 객체의 메서드로 호출될 때 그 객체가 this로 바인딩된다.
const obj = {
name: 'Eric',
sayName() {
console.log(this.name); // this는 obj를 가리킴
}
};
obj.sayName(); // 'Eric'
- 명시적 바인딩: call(), apply(), bind() 메서드를 사용해 this를 명시적으로 설정할 수 있다
function greet() {
console.log(this.name);
}
const person = { name: 'Eric' };
greet.call(person); // 'Eric', this가 person으로 설정됨
- 생성자 함수: 생성자 함수는 새로운 객체를 생성할 때, 그 객체가 this로 바인딩된다.
function Person(name) {
this.name = name;
}
const eric = new Person('Eric');
console.log(eric.name); // 'Eric'
실행 컨텍스트와 스코프
자바스크립트의 함수 실행 흐름을 이해하려면 실행 컨텍스트와 스코프 개념을 잘 알아야 한다.
실행 컨텍스트란?
실행 컨텍스트(Execution Context)는 자바스크립트 코드가 실행되는 환경을 정의한다. 모든 함수 호출이나 전역 코드가 실행될 때마다 실행 컨텍스트가 생성된다. 실행 컨텍스트는 변수 환경, 렉시컬 환경, this 바인딩 등의 정보를 포함한다.
콜 스택(Call Stack)
실행 컨텍스트는 콜 스택에 쌓여서 실행된다. 함수가 호출되면 새로운 실행 컨텍스트가 콜 스택의 맨 위에 추가되고, 함수가 종료되면 해당 컨텍스트는 스택에서 제거된다. 이는 자바스크립트가 함수의 실행 순서를 관리하는 방식이다.
호이스팅과 실행 컨텍스트의 관계
호이스팅은 자바스크립트가 변수 선언과 함수 선언을 스코프의 상단으로 끌어올리는 동작을 말한다. 실행 컨텍스트가 생성될 때, 자바스크립트 엔진은 변수와 함수 선언을 미리 처리하여 실제 실행 전에 사용할 수 있게 해준다.
스코프와 스코프 체인
스코프(Scope)는 변수와 함수에 접근할 수 있는 유효 범위를 의미한다. 자바스크립트는 렉시컬 스코프를 따르며, 이는 함수가 선언될 때의 스코프가 실행될 때에도 유지된다는 의미다.
스코프 체인
함수가 실행될 때 해당 스코프 내에서 변수를 찾지 못하면, **스코프 체인(Scope Chain)**을 따라 상위 스코프로 올라가면서 변수를 찾는다. 이 과정은 전역 스코프에 도달할 때까지 계속된다.
클로저와 스코프의 연관성
클로저(Closure)는 함수가 선언될 때의 렉시컬 환경을 기억하여, 함수가 실행되는 시점에도 그 환경에 접근할 수 있는 특성이다. 이를 통해 외부 함수의 변수를 참조하거나, 데이터 은닉을 가능하게 만든다.
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const counter = outer();
counter(); // 1
counter(); // 2
위 예시에서 inner 함수는 외부 함수 outer의 변수 count에 접근할 수 있으며, 함수가 종료된 이후에도 count를 계속해서 참조할 수 있다. 이는 클로저 덕분이다.
암시적 바인딩과 명시적 바인딩
- 암시적 바인딩: 함수가 호출되는 방식에 따라 자동으로 this가 설정된다. 예를 들어, 객체의 메서드로 호출될 때 그 객체가 this로 바인딩된다.
- 명시적 바인딩: call, apply, bind 메서드를 사용하여 this를 명시적으로 설정할 수 있다. 이 방법은 함수가 호출되는 방식에 상관없이 특정 객체를 this로 고정할 수 있다.
'JavaScript' 카테고리의 다른 글
JavaScript - 디자인 패턴 (9) | 2024.09.22 |
---|---|
JavaScript - 자바스크립트란 무엇인가? (심화편-3 객체, 프로토타입 등 ) (0) | 2024.09.22 |
JavaScript - 자바스크립트란 무엇인가? (심화편-1 타입, 변수 등) (1) | 2024.09.22 |
JavaScript - 자바스크립트란 무엇인가? (기본편) (2) | 2024.09.22 |
JavaScript - 코어 자바스트립트 정리 (4~7장, 콜백함수,클로저,프로토타입,클래스) (0) | 2024.09.22 |