1.this 키워드
객체는 상태(state)를 나타내는 프로퍼티와 동작(behavior)를 나타내는 메서드를 하나의 논리적인 단위로 묶은 복합적인 자료구조다.
동작을 나타내는 메서드는 자신이 속한 객체의 상태, 즉 프로퍼티나 메소드를 참조하고 변경할 수 있어야 한다. 이때 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 하는데, 이때 this를 사용한다.
function Circle(radius) {
// 이 시점에는 생성자 함수 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
????.radius = radius;
}
Circle.prototype.getDiameter = function () {
// 이 시점에는 생성자 함수 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
return 2 * ????.radius;
};
// 생성자 함수로 인스턴스를 생성하려면 먼저 생성자 함수를 정의해야 한다.
const circle = new Circle(5);
생성자 함수를 정의하는 시점에는 아직 인스턴스가 생성되지 않았기 때문에 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다. ⭐️
생성자 함수로 객체를 생성하려면 생성자 함수를 먼저 정의한 후 new연산자와 함께 생성자 함수를 호출해야 한다. 즉, 생성자 함수로 인스턴스를 생성하려면 먼저 생성자 함수가 존재해야 한다.
생성자 함수를 정의하는 시점에는 인스턴스를 가리키는 식별자를 알 수 없기 때문에 특수한 식별자를 사용한다. 바로 this이다.
this는 '자신이 속한 객체' 또는 '자신이 생성할 인스턴스'를 가리키는 자기 참조 변수(self-referenceing variable)다.
this는 자바스크립트 엔진에 의해 암묵적으로 생성되며, 코드 어디서든 참조할 수 있다. 함수를 호출하면 arguments객체와 this가 암묵적으로 함수 내부에 전달된다.
2. 함수 호출 방식과 this 바인딩
this가 가리키는 값, 즉 this바인딩은 함수 호출 방식에 의해 동적으로 결정된다. ⭐️
※ 렉시컬 스코프와 this 바인딩은 결정 시기가 다르다.
렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성되는 시점에 결정된다.
this 는 함수가 호출시에 결정된다.
※ 함수 객체가 생성되는 시점
함수 선언문은 코드(함수 선언문을 포함한) 평가 단계에서 함수 객체 생성
함수 표현식은 코드(함수 표현식을 포함한) 실행 단계에서 함수 객체 생성
함수를 호출하는 다양한 방식
- 일반 함수 호출
- 메서드 호출
- 생성자 함수 호출
- Function.prototype.apply/call/bind메서드에 의한 간접 호출
// this 바인딩은 함수 호출 방식에 따라 동적으로 결정된다.
const foo = function () {
console.dir(this);
};
// 동일한 함수도 다양한 방식으로 호출할 수 있다.
// 1. 일반 함수 호출
// foo 함수를 일반적인 방식으로 호출
// foo 함수 내부의 this는 전역 객체 window를 가리킨다.
foo(); // window
// 2. 메서드 호출
// foo 함수를 프로퍼티 값으로 할당하여 호출
// foo 함수 내부의 this는 메서드를 호출한 객체 obj를 가리킨다.
const obj = { foo };
obj.foo(); // obj
// 3. 생성자 함수 호출
// foo 함수를 new 연산자와 함께 생성자 함수로 호출
// foo 함수 내부의 this는 생성자 함수가 생성한 인스턴스를 가리킨다.
new foo(); // foo {}
// 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
// foo 함수 내부의 this는 인수에 의해 결정된다.
const bar = { name: 'bar' };
foo.call(bar); // bar
foo.apply(bar); // bar
foo.bind(bar)(); // bar
- 일반 함수로 호출하는 경우 기본적으로 this에는 전역 객체가 바인딩된다.(strict mode에서는 undefined)
- 메서드 내부의 this에는 메서드를 호출한 객체가 바인딩된다.(메소드 소유가 아닌 '호출'한 객체)
- 생성자 함수 내부의 this에는 생성자 함수가 (미래에) 생성할 인스턴스가 바인딩된다.
- Function.prototype.apply/call/bind 메서드에 의한 간접 호출에서는 메서드에 첫 번째 인자로 전달된 객체가 바인딩된다.
'HTML&CSS&Javascript 📚 > JS' 카테고리의 다른 글
[JS] 함수 선언 방식 : 함수 표현식 & 함수 선언식 (1) | 2023.11.24 |
---|---|
[JS Deep Dive] 13장 스코프 (1) | 2023.11.24 |
[JS Deep Dive] 19장 프로토타입 (2) | 2023.11.23 |
[Clean Code] JS 클린코드 예시 - 1 (0) | 2023.11.20 |
[JS Deep Dive] 16장 프로퍼티 어트리뷰트 (0) | 2023.09.29 |