클로저는 “내부 함수가 외부 함수의 변수를 기억하는 현상”이다.
함수 안에서 만든 내부 함수가, 자신을 감싸는 함수의 변수를 기억하는 것
function outer() {
let count = 0; // 외부 함수의 변수
return function inner() { // 내부 함수 (클로저)
count++; // 외부 함수의 변수 접근 가능!
console.log(count);
};
}
const closureFunc = outer(); // outer 실행 → 내부 함수 반환
closureFunc(); // 1
closureFunc(); // 2
closureFunc(); // 3
왜 클로저가 중요할까?
✔ 상태 유지: count 값이 초기화되지 않고 계속 유지됨
✔ 데이터 은닉: count는 outer() 바깥에서 직접 접근할 수 없음.
✔ 함수형 프로그래밍에서 많이 사용
클로저가 없으면 어떻게 될까?
function noClosure() {
let count = 0;
count++;
console.log(count);
}
noClosure(); // 1
noClosure(); // 1 (다시 초기화됨!)
클로저 없이 함수 실행하면 count가 초기화되지만, 클로저를 사용하면 값이 유지된다
this는 “함수가 실행될 때 결정되는 ’실행 컨텍스트(Execution Context)’를 가리키는 키워드” 이다.
this가 가리키는 값은 ‘함수가 호출되는 방식’에 따라 달라진다
상황 | this가 가리키는 값 |
---|---|
1️. 일반 함수 호출 | undefined (엄격 모드) 또는 window (브라우저) |
2️. 객체의 메서드 호출 | 메서드를 호출한 객체 |
3️. new 키워드 사용 (생성자 함수) | 새로 생성된 인스턴스 객체 |
4️. 화살표 함수 사용 | this를 부모 스코프(외부 함수)의 this로 고정 |
1. 일반 함수 호출
function sayHello() {
console.log(this);
}
sayHello(); // 일반 함수 실행 → this는 window (또는 undefined)
브라우저 환경에서는 window 객체를 가리킴.
"use strict"; // 엄격 모드 활성화
function sayHello() {
console.log(this);
}
sayHello(); // undefined
strict mode("use strict")에서는 undefined가 된다.
2️. 객체의 메서드 호출
const person = {
name: "료니",
greet() {
console.log(this.name);
}
};
person.greet(); // "료니" (this는 person 객체)
this는 이 메서드를 호출한 객체를 가리킴.
3️. 생성자 함수 (new 키워드 사용)
function Person(name) {
this.name = name;
}
const me = new Person("료니");
console.log(me.name); // "료니"
new 키워드를 쓰면 새로운 객체가 생성되고, this가 그 객체를 가리킴.
4️. 화살표 함수 (this 바인딩)
const obj = {
name: "료니",
greet: () => {
console.log(this.name);
}
};
obj.greet(); // undefined (this는 obj가 아니라 window)
화살표 함수는 this를 자신을 감싸는 부모 스코프의 this로 고정한다.
즉, obj.greet() 안의 this는 obj가 아니라 전역 객체(window)를 가리킴.
프로토타입은 “객체가 상속받을 수 있는 속성과 메서드들을 저장하는 공간”이다.
“모든 객체는 숨겨진 proto(프로토타입 링크)를 가지고 있으며, 이걸 통해 상속을 구현한다.”
프로토타입 기본 개념
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`안녕! 나는 ${this.name}이야.`);
};
const me = new Person("료니");
me.sayHello(); // "안녕! 나는 료니야."
me 객체에는 sayHello 메서드가 없음
하지만 Person.prototype에 있기 때문에 proto를 통해 접근 가능
프로토타입 체인 (Prototype Chain)
console.log(me.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
모든 객체는 proto를 따라 위쪽으로 상속 구조(체인)를 따라가며 프로퍼티를 찾음.
최종적으로 Object.prototype까지 올라감.
객체 연결 장치는 “프로토타입 체인을 따라 상속되는 구조” 이다.
객체가 자신의 프로퍼티를 찾을 때 없으면 proto를 따라가서 부모 객체에서 찾는다
객체 연결 장치 예제
const parent = {
hello() {
console.log("안녕, 나는 부모야!");
}
};
const child = Object.create(parent); // parent를 상속받는 객체 생성
child.hello(); // "안녕, 나는 부모야!"
child 객체에는 hello() 메서드가 없음.
하지만 proto를 따라 parent에서 hello()를 찾고 실행한다.
결론적으로
개념 | 역할 | 핵심 포인트 |
---|---|---|
클로저(Closure) | 내부 함수가 외부 함수의 변수를 기억 | return으로 내부 함수 반환 |
this | 실행 컨텍스트에 따라 값이 결정 | 일반 함수, 메서드, new, 화살표 함수에 따라 다름 |
프로토타입(Prototype) | 객체의 부모 역할, 상속 기능 제공 | proto를 통해 프로퍼티 찾기 |
객체 연결 장치(Prototype Chain) | 프로토타입을 따라 객체 간 연결 | 부모 → 자식으로 메서드 상속 |