일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- never타입
- textarea autosize
- tailwindcss
- react
- 해쉬
- NextAuth
- 정렬
- 버블정렬
- react-query
- nextjs
- aws lightsail
- 스택
- js알고리즘
- 큐
- 알고리즘
- TypeScript
- JavaScript
- 투포인터
- 슬라이딩윈도우
- cookie
- 그리디
- 빅오
- 블로그만들기
- isNaN
- next.js
- typscript
- 라이프사이클
- styled-components
- nestjs
- Algorithm
- Today
- Total
far
[Javascript] This에 대하여 본문
1. this
this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-referencing variable)다. this를 통해 자신이 속한 객체 똔느 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다. this는 자바스크립트 엔진에 의해 암묵적으로 생성되며, 코드 어디서든 참조할 수 있다. this는 지역 변수처럼 사용할 수 있지만 this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
const circle = {
radius: 5,
getDiameter() {
return 2 * this.radius;
}
};
console.log(circle.getDiameter()); // 10
const circle = {
this.radius = radius;
};
Circle.prototype.getDiameter = function() {
return 2 * this.radius;
};
const circle = new Circle(5);
console.log(circle.getDiameter()); // 10
this는 위와 같이 상황에 따라 가리키는 대상이 다르다.
2. 함수 호출 방식과 this 바인딩
자바스크립트의 this는 함수가 호출되는 방식에 따라 this에 바인딩될 값, 즉 this 바인딩이 동적으로 결정된다.
2.1. 일반 함수 호출
function foo() {
console.log(this); // window
function bar() {
console.log(this); // window
}
bar();
}
foo();
일반 함수로 호출된 모든 함수(콜백 함수, 중첩 함수 등)는 this에 전역 객체가 바인딩된다. (기본적으로 this에는 전역 객체가 바인딩된다.)
const value = 1;
const obj = {
value: 100,
foo() {
// 방법1 : 변수에 할당한 뒤 변수를 참조
const that = this;
setTimeout(function () {
console.log(that.value); // 100
}, 100);
// 방법2 : bind 사용
setTimeout(function () {
console.log(that.value); // 100
}.bind(this), 100);
}
}
위와 같이 메서드 내부의 중첩 함수나 콜백 함수의 this 바인딩을 메서드의 this 바인딩과 일치시키면, 또는 JS에서 제공되는 메서드를 사용하면 this를 사용할 수 있다.
2.2. 메서드 호출
메서드 내부의 this에는 메서드를 호출한 객체, 즉 메서드를 호출할 때 메서드 이름 앞의 마침표(.) 연산자 앞에 기술한 객체가 바인딩된다. 주의할 점은 메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩 된다는 것이다.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
const me = new Person('Lee');
console.log(me.getName()); // Lee
Person.prototype.name = 'Kim';
console.log(Person.prototype.getName()); // Kim
me의 경우 getName 메서드를 호출한 객체는 me이기 때문에 this.name이 Lee가 된다. 하지만 Person.prototype의 경우 getName을 호출한 객체는 Person.prototype이 되어 Kim이 호출된다.
2.3. 생성자 함수 호출
생성자 함수 내부의 this에는 생성자 함수가 생성할 인스턴스가 바인딩된다.
const circle = {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
}
};
const circle1 = new Circle(5);
const circle2 = new Circle(10);
console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20
2.4. apply, call, bind 메서드에 의한 간접 호출
apply, call, bind 메서드는 Function.prototype의 메서드다. 이들 메서드는 모든 함수가 상속받아 사용할 수 있다.
function getThisBinding() {
return this;
}
const thisArg = { a: 1 };
console.log(getThisBinding()); // window
console.log(getThisBinding.apply(thisArg)); // {a: 1}
console.log(getThisBinding.call(thisArg)); // {a: 1}
console.log(getThisBinding.bind(thisArg)()); // {a: 1}
console.log(getThisBinding.bind(thisArg)); // getThisBinding
apply와 call 메서드는 this를 바인딩하면서 함수를 호출한다는 점은 같지만, 두번째 인자를 하나씩 넘기느냐 배열로 넘기느냐의 차이가 있다.
function getThisBinding() {
return this;
}
const thisArg = { a: 1 };
console.log(getThisBinding()); // window
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: f, Symbol(Symbol.iterator): f]
// {a: 1}
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: f, Symbol(Symbol.iterator): f]
// {a: 1}
bind 메서드는 this가 바인딩된 새로운 함수를 리턴하며, 메서드의 this와 메서드 내부의 중첩 함수 또는 콜백 함수의 this가 불일치하는 문제를 해결하기 위해 유용하게 사용된다.
const person = {
name: 'Lee',
foo(callback) {
setTimeout(callback.bind(this), 100);
}
};
person.foo(function() {
console.log(this.name); // Lee
});
참고: 모던 자바스크립트 Deep Dive
'Javascript' 카테고리의 다른 글
[Javascript] innerHTML, innerText, textContent 차이 (0) | 2023.03.30 |
---|---|
[Javascript] 실행 컨텍스트 (0) | 2023.03.26 |
[Javascript] 엄격 모드(Strict mode) (0) | 2023.03.24 |
[Javascript] 프로토타입(Prototype) (0) | 2023.03.23 |
[Javascript] 프로퍼티 어트리뷰트 (0) | 2023.03.22 |