JS - THIS
this란?
- 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수.
- this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
- this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.
바인딩, 바인딩 하는데 바인딩이 뭐죠?
⇒ 식별자와 값을 연결하는 과정을 말합니다.
다시, this로 돌아와서…
- this는 함수 호출 방식에 따라 동적으로 호출된다.
- 화살표 함수의 경우, 일반 함수와 다르게 상위 스코프의 this를 가리킨다. ㅤ ㅤ ㅤ ㅤ
함수 호출 방식에 따른 This 바인딩
=> 딱 필수적으로 알아가면 좋은 함수 호출 방식은 3가지가 있다.
- 일반 함수 호출
- 메서드 호출
- 생성자 함수 호출
ㅤ ㅤ
1. 일반 함수 호출
=> 이 방식으로 함수 호출 후, this는 전역 객체가 바인딩 된다.
다만, 예외인 경우가 조금 있는데 화살표 함수를 사용했을 때이다.
아래의 코드를 보자.
var value = 1;
const obj = {
value: 100,
foo() {
console.log("foo's this : ", this); // obj의 this
setTimeout(function () {
console.log(this); //window
}, 100);
setTimeout(() => {
console.log(this); //obj의 this
}, 200);
},
};
obj.foo();
- 객체 obj 내에 프로퍼티로 있는 foo()함수의 경우, 메서드 호출에 속하기 때문에 obj를 가리킨다.
- foo 내부의 첫 번째 setTimeout의 경우, 안에 매개변수로 들어가는 함수가 일반 함수로 작성되었기 때문에 console.log(this)에서 this는 전역 객체이다.
- foo 내부의 두 번째 setTimeout의 경우, 안에 매개변수로 함수가 들어가는 것은 똑같으나 “화살표 함수” 방식으로 작성이 되었기 때문에 상위 스코프의 this(obj의 this)가 반환된다.
이렇듯이, 화살표 함수는 자신의 상위 스코프의 this를 가져오는 특징이 있다.
이걸 모르고 짰을 땐, 대체 왜 내 this는 아무것도 들어있지 않지? 라는 고통을 많이 겪었던 것 같다… 꼭 알아두도록 하자. ㅤ ㅤ
?? : 아니 잠깐만요. 그럼, 일반함수로 this를 쓸때는 꼭 전역 객체밖에 못 받는 건가요? ⇒ 아니다. 꼼수를 쓰면 가능하다.
약간 코드를 바꾸어 보았다.
var value = 1;
const obj = {
value: 100,
foo() {
const that = this;
setTimeout(function () {
console.log(that); //that => obj의 this
}, 100);
},
};
obj.foo();
이렇게 특정 변수에 this를 저장하면 하위 일반 함수에서도 상위 스코프의 this를 사용할 수 있다. ㅤ ㅤ ㅤ
2. 메서드 호출
=> 해당 메소드를 소유한 객체가 아닌 호출한 객체에 바인딩 된다. => 프로토타입 객체도 일반적인 메소드의 this 바인딩 규칙을 따른다.
바로 코드를 보자.
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
var song = new Person("song");
song.getName(); //"song"
Person.prototype.name = "kim";
Person.prototype.getName(); // "kim"
- 생성된 객체 song.getName() 호출시의
this는 메소드를 호출한 객체인 song객체이다. 따라서 song.name인 “song”이 리턴된다. - prototype객체의 getName()을 호출시의
this는 마찬가지로 메소드를 호출한 객체인 Person.prototype객체이다. 따라서 “kim”이 리턴된다. ㅤ ㅤ ㅤ
3. 생성자 함수 호출
=> 생성자 함수가 (미래에) 생성할 인스턴스가 바인딩 된다. => 만약, new 연산자를 붙이지 않으면 일반 함수처럼 동작한다.
생성자 함수의 호출의 코드예시는 이 곳에서 뼈저리게 느낄 수 있었다… => 프로그래머스 프론트엔드 과제 -고양이 사진첩
index.js 부분을 확인해보면 도움이 될지도 모른다…