JavaScript의 this 키워드: 스코프에 따른 동작 방식
JavaScript에서 this 는 함수가 호출되는 방식에 따라 가리키는 대상이 달라지는 동적 바인딩 키워드다. 상황에 따라 this 의 참조가 바뀌기 때문에 정확한 동작 방식을 이해하는 것이 좋다
1. 전역
- 전역에서 사용될 때, this 는 전역 객체를 참조한다.
- 브라우저 환경에서는 window 객체, Node.js 환경에서는 global 객체를 가리킨다
console.log(this) // 브라우저에서는 window, Node.js에서는 global
2. 메서드
- 객체의 메서드에서 this 는 해당 메서드가 속한 객체를 참조한다
- 즉, 메서드가 호출될 때만 this 는 해당 객체를 참조하므로, 호출 위치가 중요하다
const person = {
name: "Alice",
sayHello() {
console.log(`Hello, ${this.name}`);
}
};
person.sayHello(); // "Hello, Alice" - this는 person 객체를 참조
3. 함수
- 일반 함수에서의 this 는 호출 방식에 따라 달라지며, 기본적으로 전역 객체를 가리킨다
- use strict 모드에서는 undefined 가 된다 (▶하단 설명 참조)
function showThis() {
console.log(this);
}
showThis(); // 전역 객체
"use strict":
function showThisStrict() {
console.log(this)
}
showThisStrict(); // undefined
4. 생성자 함수
- new 키워드를 사용해서 생성자 함수를 호출하면 this 는 새롭게 생성되는 객체를 참조한다
- 이때 this 는 새 인스턴스와 연결된다
function Person(name) {
this.name = name;
}
const alice = new Person("Alice");
console.log(alice.name); // "Alice" - this 는 새로 생성된 alice 객체
5. 화살표 함수
- 화살표 함수는 상위 스코프의 this 를 그대로 상속받는다
- 일반 함수와 달리 this 바인딩이 고정되어 있으며, 호출 방식에 상관없이 this 가 변하지 않는다. (▶하단 설명 참조)
const person = {
name: "Alice",
sayHello: () => {
console.log(this.name); // undefined - this는 전역 객체 참조
}
};
person.sayHello();
6. 명시적 바인딩: call, apply, bind
- call 과 apply 메서드를 사용하면 함수 호출 시 this 를 특정 값으로 설정할 수 있다 (▶하단 설명 참조)
- bind 메서드는 this 를 영구적으로 고정하는 새로운 함수를 반환한다
function greet() {
console.log(`Hello, ${this.name}`);
}
const user = { name: "Alice" };
greet.call(user); // Hello, Alice
greet.apply(user); // Hello,Alice
const boundGreet = greet.bind(user);
boundGreet(); // Hello, Alice
상황 | this 가 가리키는 대상 |
전역 문맥 | 전역 객체(window 또는 global) |
객체의 메서드 | 메서드가 호출된 객체 |
일반 함수 | 기본적으로 전역 객체, 엄격 모드에서는 undefined |
생성자 함수 | 새로 생성되는 객체 |
화살표 함수 | 상위 스코프의 this |
call, apply, bind | 지정한 객체 |
엄격 모드 ("use strict")란 무엇인가?
ES5부터 도입된 자바스크립트에서 더 엄격한 규칙을 적용하도록 하는 모드이다. 엄격 모드를 활성화하면 일반적인 코드에서 허용되는 몇 가지 관행을 제한하여, 더 안전하고 성능이 좋은 코드를 작성할 수 있다
- 엄격 모드 활성화 방법: 코드 파일 전체나 함수 내부에 "use strict"; 를 추가한다.
"use strict";
// 또는 함수 내에서
function example() {
"use strict";
// 엄격 모드 적용
}
- this 가 전역 객체를 참조하는 대신, 함수 내에서 undefined 로 설정된다.
- 암묵적 전역 변수 생성을 금지한다
- 같은 이름의 매개변수 사용을 금지한다
- eval 함수의 사용을 제한하고, 변수 선언에 영향을 미치지 않는다
호출 방식에 상관없이 this 가 고정된다는 것은?
화살표 함수에서 this 는 고유의 this 를 가지지 않으며, 상위 스코프의 this 를 그대로 상속한다. 따라서 어떤 방식으로 호출하더라도 this 가 변하지 않고 고정된다는 의미이다.
예를 들어, 화살표 함수는 호출 위치나 호출 방법에 관계없이 정의될 당시의 스코프에서 this 를 가져온다
const person = {
name: "Alice",
greet: () => {
console.log(this.name); // 상위 스코프의 `this`를 참조 (여기서는 전역 객체)
}
};
person.greet(); // undefined - 화살표 함수는 호출 방식에 상관없이 전역 `this`를 사용
일반 함수에서는 호출 방식에 따라 this 가 달라지지만, 화살표 함수는 this 가 고정되므로 호출 문맥에 영향을 받지 않는다
명시적 바인딩이란 무엇인가?
명시적 바인딩은 this 를 특정 객체로 명확하게 설정할 수 있는 방법을 의미하며, JavaScript에서 제공하는 call, apply, bind 메서드를 통해 구현된다
- call : 함수를 호출하면서 this 를 특정 객체로 설정한다. 인수는 하나씩 나열한다
function greet() {
console.log(`Hello, ${this.name}`);
}
const user = { name: "Alice" };
greet.call(user); // Hello, Alice
- apply : call 과 동일하지만, 인수를 배열 형태로 전달한다
greet.apply(user); // Hello, Alice
- bind : this 가 특정 객체로 영구적으로 고정된 새 함수를 반환한다.
const boundGreet = greet.bind(user);
boundGreet(); // Hello, Alice
명시적 바인딩은 this 가 필요한 특정 객체를 참조하도록 강제로 설정할 때 유용하게 사용된다
'JavaScript' 카테고리의 다른 글
[JavaScript] 리터럴 정규식과 RegExp 객체 (1) | 2024.11.16 |
---|---|
[JavaScript] 정규식 (0) | 2024.11.16 |
[JavaScript] == (느슨한 비교) 와 === (엄격한 비교) (0) | 2024.11.09 |
[JavaScript] Truthy와 Falsy 값 (2) | 2024.11.09 |
[JavaScript] 변수 선언하기: ver, let, const (1) | 2024.11.09 |