자바스크립트의 기본부터 천천히 공부하고 있다.
공부한 내용을 나만의 방식대로 정리해두어야 나중에 까먹어도 쉽게 다시 이해할 수 있을 것 같아 정리했다.
핵심1. this는 '자신이 속한 객체를 가리키는 변수' 이다.
핵심2. this는 자신을 '호출'하는 방법에 따라 다른 값을 가리킨다.
var someone = {
name: 'KMS',
someFunction: function() {
console.log(this);
}
}
위와 같은 객체를 하나 만들어, 여러 케이스를 접해보며 this를 알아가보려한다.
someone이라는 객체는 someFunction이라는 속성을 가지고 있으며, 이 속성엔 this를 콘솔에 찍는 함수가 담겨있다.
// case 1
someone.someFunction();
첫번째 케이스 코드는 위와 같다.
이 경우, 콘솔에 찍힌 this는 어떤 것을 자기 자신으로 가리키고 있을까?
case 1의 결과는 위처럼 someone 객체를 this로 가리키고 있다.
someFunction을 직접적으로 호출(실행)한 객체가 someone이기 때문이다.
// case 2
var myFunction = someone.someFunction;
myFunction(); // <--- 호출포인트
두번째 케이스 코드는 위와 같다.
myFunction 이라는 새로운 객체에 담았을 뿐, 실제 내용은 case 1과 다를 바가 없다.
이 경우엔 어떤 것을 자기 자신으로 가리키고 있을까?
분명 동일한 내용인데 워째서 이번엔 window 객체를 this로 가리키고 있는겨!?
이제부터 this의 핵심인 '호출(실행)하는 방법에 따라 = 호출(실행)한 주체에 따라' 달라지는 this 값들에 대해 이야기해볼 수 있다.
case 1과 case 2 둘 다 someone 객체의 someFunction을 실행하는 내용임엔 변화가 없다.
그러나 case 1의 경우, someFunction을 실행하는 주체가 someone 객체 그 자체인 반면,
case 2의 경우 myFunction이라는 함수를 실행하는 주체는 전역객체인 window 객체이다.
(쉽게 나의 언어로 정리를 한번 해보자면, 호출이 되는 순간, 날 부른 상위객체가 무엇일까? 생각해보면 쉬울 것 같다.
case 2는 myFunction을 호출한 것이다. someFunction을 직접 호출한게 아니라...)
// case 3
document.getElementById('btn').addEventListener('click', someone.someFunction);
// 버튼이벤트를 등록하는 것은 함수의 '호출'이 아니다. 실제 함수의 호출은 버튼이 클릭 되었을 때 발생하는 것.
그렇다면 이런 식으로 버튼에 함수를 붙여 호출하면 this는 무엇을 가리키겠는가?
우리가 여태 '함수를 호출한 주체'가 this라고 했으니, 버튼이 클릭될 때 호출되는 함수의 실행주체는 누구겠는가?
바로 버튼 그 자체가 된다.
왜냐면 버튼이 함수를 불렀으니까...
this는 이렇게 호출(실행)한 방식에 따라 다른 값을 가리키게 된다.
그런데 이 this값을 호출한 방식에 상관없이 고정시킬 수는 없을까?
뭐어! bind란게 있다고!?
// case 4 : bind
var bindedSomeFunction = myFunction.bind(someone);
bindedSomeFunction(); // 호출방식1
document.getElementById('btn').addEventListener('click', bindedSomeFunction); // 호출방식2
위에 case 2에서 만들었던 myFunction 이라는 함수에 'someone' 객체를 묶어(bind)주었다.
그렇다면 아래 두 줄의 코드처럼 서로 다른 방식으로 호출하게 되면 this값이 어떻게 될까?
우리가 위에서 알아본 지식으론 다른 값을 표출해야하는데...
띠이이ㅣㅣㅣㅣㅣ용용용
동일한 객체(someone)을 this로 가리키고 있는 모습이다.
이렇듯 bind 함수를 사용하면, 호출하는 방식에 상관없이 this값을 고정시켜 사용할 수 있다.
사실 this 같은 경우에는 동일한 this라는 키워드 하나가 여러 모습으로 변화하기 때문에 글로 보는 것이 훨씬 헷갈리는 것 같다.
실제로 코드를 한번 적어보면, 많이들 애를 먹는 만큼 어렵고 헷갈리는 개념은 아닌 것 같다.
라고 쓰고 나중에 또 헷갈리겠지? ㅋㅅㅋ
이 시점에서 글 첫 부분에 있던 핵심을 다시 짚어보도록 하자.
핵심1. this는 '자신이 속한 객체를 가리키는 변수' 이다.
핵심2. this는 자신을 '호출'하는 방법에 따라 다른 값을 가리킨다.
this를 사용하지 않아도, 심지어 몰라도 기능을 구현하는데엔 문제가 없다.
다만 this를 알면 조금 더 효율적이고 깔끔한 코드를 짜는데에 도움이 되지않을까.
아래는 전체 정리 코드이다.
// this 키워드란? 자신이 속한 객체를 가리키는 자기참조변수이다.
// this는 자신을 '호출'하는 방법에 따라 다른 값을 가리키게 된다.
// => this는 자신을 '호출'한 주체를 가리킨다.
var someone = {
name: 'KMS',
someFunction: function() {
console.log(this);
}
}
// case 1
someone.someFunction();
// someFunction 함수를 직접적으로 호출한 주체는 someone이 된다.
// 정리코멘트: this는 someFunction을 직접적으로 호출한 주체인 someone이다.
// case 2
var myFunction = someone.someFunction;
myFunction();
// case 1과 같이 동일한 someFunction을 호출하고 있다.
// 정리코멘트: this는 myFunction을 호출한 주체인 window 객체(=글로벌 객체, 전역객체)이다.
// case 3
document.getElementById('btn').addEventListener('click', someone.someFunction);
// 버튼에 someone.someFunction을 클릭이벤트로 달아주었다. = 이벤트로 달아주는 시점에는 '호출'이 이루어지지 않는다.
// 실제 클릭이벤트가 실행되어 함수가 '호출'되는 시점은 '버튼이 눌렸을 때'
// 정리코멘트: this는 someFunction(or myFunction)을 호출한 주체인 버튼이다.
// case 4 : bind
/*
var bindedSomeFunction = myFunction.bind(someone);
console.log('bindedSomeFunction()의 결과:')
bindedSomeFunction();
console.log('button을 클릭했을 때:')
document.getElementById('btn').addEventListener('click', bindedSomeFunction);
*/
// bind는 호출한 방식에 상관없이 this를 고정시키는 함수를 말한다. (위 코드에서는 someone을 this로 고정)
'프로그래밍 > 정리노트' 카테고리의 다른 글
정리노트: var, let, const (0) | 2022.08.14 |
---|---|
정리노트: 스코프 (0) | 2022.08.13 |
정리노트: 호이스팅 (0) | 2022.08.13 |
정리노트: 브라우저의 렌더링 원리 (0) | 2022.08.13 |
정리노트: 클로져(Closure)랑 놀기 (0) | 2022.06.03 |