Jiyong's STUDY
Javascript의 this와 call 본문
this는 객체를 가리키는 포인터와 같은 존재라고 볼 수 있다.
기본적으로 this가 가리키고 있는 것은 전체를 가리키고 있는데,
브라우저의 경우 window를, node.js의 경우에는 global을 가리킨다.
객체 안에서 this를 사용하면 다음과 같이 사용된다.
const a = {
foo: 'foo',
bar: 'bar',
f1: function() {
return this.foo;
},
f2: function() {
return this.bar;
},
f3: function () {
return this;
}
}
console.log(a.f1());
console.log(a.f2());
console.log(a.f3());
--
node test.js
foo
bar
{
foo: 'foo',
bar: 'bar',
f1: [Function: f1],
f2: [Function: f2],
f3: [Function: f3]
}
--
객체 안에서 this 바인딩을 하면 a 객체를 가리키는 것을 볼 수 있다. 정확히, 객체의 메소드에서 해당 객체를 가리키게 변화시킨다.
그래서 객체의 메소드 외에는 어떨까?
const foo = (c, d) => {
let a = 1;
let b = 2;
bar(c, d);
console.log('foo:', a, b);
}
const bar = (a, b) => {
this.a = a;
this.b = b;
}
foo(3, 4);
console.log('this case:', this.a, this.b);
--
node test.js
foo: 1 2
this case: 3 4
--
나름대로 class의 setter처럼 만들어봤다.
class에서 setter를 사용하여 클래스 내부 변수를 변경하고 사용하는데, 여기서도 this로 그게 가능할까?
아니다. 전혀 그렇지 않다.
foo를 실행시켜 얻은 결과 아주 엉뚱한 놈이 변경되었다.
변경하고자 한 foo의 지역 변수가 아니라 전역 객체에 없던 a와 b를 박아넣은 셈이다.
다시 정리를 하자면, this는 객체의 메소드를 사용할 때 객체를 가리키는 포인터가 된다. 그 외엔 기본값인 global 또는 window다.
그러니까 함수에서 this를 사용하고자 할 때엔 다른 방식을 생각해야 한다.
즉 함수에서 this를 사용하는 경우에는 자기 자신도 객체이지만 자기 자신이 속해있는, 즉 자신의 부모 객체를 반환한다는 것이다.
그렇기에 원하는 객체를 가리키게 하기 위해서 call이라는 것을 사용한다. 또는, 함수를 new로 생성하기도 한다.
그래서 call이 뭐냐?
func.call(thisArg[, arg1[, arg2[, ...]]])
Function.prototype.call()
즉 모든 함수에 내장된 메소드다. 이 call이라는 메소드의 역할은 함수를 호출하는 것에 있다.
인자를 보면 thisArg, arg1, arg2, ... 순으로 가는데 첫 번째 인자에는 this를 바인딩할 객체를 넣어줘야 한다.
const foo = {
first: 1,
second: 2,
third: 3,
};
const bar = function() { return this.first; }
console.log(bar.call(foo));
f();
--
node test.js
1
1
--
다음과 같이 사용될 수 있다. 여기서 bar에 담긴 익명 함수는 그냥 function으로 작성해도 되고 프로퍼티로 작성해도 된다.
다만 절대 화살표 함수를 사용해서는 안 된다.
화살표 함수를 사용하는 경우에는 스코프가 꼬여버린다.
3줄 요약
1. this는 객체를 가리키는 포인터
2. 객체의 메소드에서의 this는 그 객체를 가리키고 있고 다른 경우에는 기본값 (global or window)
3. call은 함수에 this 바인딩을 시켜주고 화살표 함수는 금지
'Web > 자바스크립트' 카테고리의 다른 글
Javascript의 call, apply, bind (0) | 2021.06.29 |
---|---|
Javascript의 Hoisting과 Scope (0) | 2021.06.28 |
클로저(Closure)란? (0) | 2021.06.24 |
Javascript의 실행 컨텍스트 (0) | 2021.05.26 |
Javascript의 함수 (0) | 2021.05.26 |