컨텍스트
- 자바스크립트에서 컨텍스트(context)는 특정 코드가 실행될 때의 환경으로 컨텍스트는 코드가 어떻게 해석되고 실행되는지를 결정하는 중요한 개념
- 주로 실행 컨텍스트와 this 컨텍스트라는 2가지 측면에서 다뤄짐
실행 컨텍스트
자바스크립트 코드가 실행되는 환경으로 아래 세가지 주요 요소 포함
- 변수 객체: 함수 내에서 선언된 변수, 함수 선언문 등을 저장
- 스코프 체인: 현재 실행 컨텍스트와 부모 컨텍스트의 변수 객체를 참조하는 체인으로 변수 접근을 제어
- this 바인딩: this가 어떤 객체를 참조할지 결정
실행 컨텍스트는 크게 전역 컨텍스트와 함수 컨텍스트로 나뉨
- 전역 컨텍스트: 스크립트 처음 실행될 때 생성, 전역 변수 관리, 브라우저 환경에서는 window 객체가 전역 컨텍스트의 this
- 함수 컨텍스트: 함수가 호출될 때마다 생성되며, 함수 내부의 변수 및 함수 선언문을 관리
실행 컨텍스트 관련 용어
스코프(Scope)
변수가 접근할 수 있는 범위를 의미합니다. 자바스크립트에서 스코프는 전역 스코프(Global Scope)와 함수 스코프(Function Scope)로 나뉩니다. ES6 이후에는 블록 스코프(Block Scope)도 추가되었습니다.
호이스팅(Hoisting)
자바스크립트에서 변수 선언과 함수 선언이 실행 전에 해당 스코프의 최상단으로 끌어올려지는 현상을 말합니다. 변수 선언이 호이스팅되지만, 변수 할당은 호이스팅되지 않습니다.
클로저(Closure)
함수가 생성될 때의 외부 변수(즉, 상위 스코프의 변수)를 기억하는 함수입니다. 이로 인해 함수가 생성된 이후에도 외부 변수를 참조할 수 있습니다.
콜 스택(Call Stack)
자바스크립트가 함수를 호출할 때마다 실행 컨텍스트가 스택에 쌓입니다. 함수가 종료되면 해당 컨텍스트가 스택에서 제거됩니다.
렉시컬 환경(Lexical Environment)
변수와 함수 선언을 포함하고 있는 환경입니다. 실행 컨텍스트는 렉시컬 환경을 참조하여 해당 컨텍스트 내에서 변수와 함수를 관리합니다.
this 컨텍스트
현재 실행중인 코드에서 this가 참조하는 객체 의미
this
- this는 함수가 호출되는 방식에 따라 달라지는 동적인 참조
- 전역 컨텍스트에서 전역 객체 (window/global)을 가리킵니다.
- 메서드에서는 메서드를 소유한 객체를 참조
- 생성자 함수에서는 새로 생성된 객체 참조
- 화살표 함수는 this를 가지지 않고, 상위 스코프의 this를 참조
- call, apply, bind를 통해 this를 명시적으로 지정
this의 주요 동작방식
1. 전역 컨텍스트에서의 this
전역 컨텍스트에서, 즉 함수 외부에서 this는 전역 객체를 가리킵니다. 브라우저 환경에서는 window 객체를, Node.js 환경에서는 global 객체를 참조합니다.
console.log(this); // 브라우저에서는 window 객체, Node.js에서는 global 객체
2. 함수 내부에서의 this
일반 함수 내에서 this는 기본적으로 전역 객체를 가리킵니다.(엄격모드가 아닐때) 그러나 엄격모드('use strict')일때는 this가 undefined가 됩니다.
function showThis() {
console.log(this);
}
showThis(); // 전역 객체 (window 또는 global)
function showStrictThis() {
'use strict';
console.log(this);
}
showStrictThis(); // undefined
3. 객체 메서드 내에서의 this
객체의 메서드에서 this는 해당 메서드를 호출한 객체를 참조합니다.
const person = {
name: "Alice",
greet: function () {
console.log(`Hello, my name is ${this.name}`);
}
};
person.greet(); // "Hello, my name is Alice"
4. 생성자 함수와 this
생성자 함수 내에서 this는 새로 생성된 객체를 참조합니다. 생성자 함수는 대문자로 시작하는 것이 일반적이며, new 키워드와 함께 호출됩니다.
function Person(name) {
this.name = name;
}
const person1 = new Person("Jimmy")
console.log(person1.name); //"Jimmy"
5. call, apply, bind를 사용한 this
call, apply는 함수를 호출하면서 this를 명시적으로 설정할 수 있게 해줍니다. bind는 새로운 함수로 this가 바인딩된 함수를 반환합니다.
function greet() {
console.log(`Hi, my name is ${this.name}`);
}
const person = {name: 'goddino'};
greet.call(person); //"Hi, my name is goddino"
greet.apply(person); //"Hi, my name is goddino"
const boundGreet = greet.bind(person); //bind로 새로운 함수 생성
boundGreet(); //"Hi, my name is goddino"
6. 화살표 함수에서의 this
화살표 함수에서는 자신만의 this를 가지지 않고, 자신이 선언된 렉시컬 컨텍스트(상위 스코프)를 그대로 참조합니다. 따라서 화살표 함수 내부의 this는 해당 함수가 정의된 위치의 this와 동일합니다.
const person = {
name: "goddino",
greet: function () {
const arrowGreet = () => {
console.log(`Hi, my name is ${this.name}`)
}
}
};
person.greet(); //"Hi, my name is goddino"
//이 코드에서 arrowGreet 함수는 greet 메서드의 this, 즉 person 객체를 참조합니다.
7. DOM 이벤트 핸들러에서의 this
this는 이벤트가 발행한 요소를 참조합니다.
document.getElementById("btn").addEventListener("click", function () {
console.log(this) //클릭된 요소, 버튼
})
그러나 화살표 함수를 사용한 경우, this는 상위 스코프의 this를 참조합니다.
document.getElementById("btn").addEventListener("click", () => {
console.log(this); //상위 스코프의 this, 즉 전역 객체인 window
})
'개발 > Javascript' 카테고리의 다른 글
[js] Slice, Splice의 비교 (0) | 2024.08.24 |
---|---|
[프론트엔드 예상 면접] 호이스팅, 스코프 (0) | 2024.08.23 |
[프론트엔드 예상 면접] Promise와 Async/await 차이점 (0) | 2024.08.13 |
[jQuery] css 가져오기 변경하기 (0) | 2023.07.10 |
[jQuery] 페이지마다 해당 메뉴명 스타일 주기 (0) | 2023.05.10 |
댓글