개발하면서 은근 자주 찾아볼 수 있는 this 키워드는 뜻이 매우 다양합니다.
사용하는 환경에 따라서 4개 이상의 각각 다른 뜻을 가지고 있는데
이번 기회에 총정리해봅시다.
1-1. 그냥 쓰거나 함수 안에서 쓰면 this 는 window를 뜻합니다.
그냥 HTML 파일 아무거나 하나 만들고 중간에 <script>태그를 열어서
일단 this라는 키워드를 콘솔창에 출력해보도록 합시다.
그러면 this 키워드는 그냥 window 어쩌구 이런 값이 나옵니다.
비슷하게 일반 함수 내에서 this라는 값을 불러보면
똑같이 this라는 값은 window 라고 출력됩니다.
이것이 this의 첫째 뜻입니다. 그냥 window입니다.
Q. window가 뭔가요?
A. window는 모든 전역변수, 함수, DOM을 보관하고 관리하는 전역객체입니다.
라고 구글검색 번역투로 설명하면 이해가 잘 안되니 좀 쉽게 비유해보자면
여러분들일 쓰는 자바스크립트 함수들 있잖아요?
document.getElementById(), alert(), console.log()
이런 함수들을 보관하는 보관소입니다. 보관소는 특별한건 아니고 그냥 큰 {오브젝트}일 뿐입니다.
또한 여러분이 전역변수를 만들었을 때도 이 값을 보관해줍니다.
이렇게 변수를 큰 공간에 만들면 x라는 변수는 window라는 큰 오브젝트안에 자동적으로 생성됩니다.
함수도 마찬가지입니다.
1-2. strict mode일때 함수 안에서 쓰면 this는 undefined입니다.
IE 10버전 이상에선 'use strict'라는 키워드를 페이지 최상단에 추가하면
strict mode로 자바스크립트를 작성가능합니다.
strict mode에선 var 키워드 없이 변수를 선언하거나,
변수를 arguments라는 이상한 키워드로 선언하거나 그런 실수를 방지해줍니다.
strict mode에선 this 키워드를 일반함수 안에서 불렀을 때 undefined라는 값으로 강제로 지정해줍니다.
외울게 하나 더 생겼군요.
2. object 자료형 내에 함수들이 있을 수 있는데 거기서 this값은 '주인님'을 뜻합니다.
object1안에 있는 '함수' 라는 함수를 호출해보면 콘솔창에 다음과 같이 출력될 겁니다.
이게 뭐냐면 그냥 여러분이 방금 만든 object1 입니다.
그래서 메소드안에서 this를 쓰시면 this는 메소드를 가지고 있는 object를 뜻합니다.
쉽게 외우고 싶다면 this는 '메소드의 주인님'을 지칭합니다.
그럼 밑의 예제의 this는 무슨 값이 출력될까요?
this는 메소드를 담고있는 주인님을 뜻하기 때문에 함수()를 담고있는 주인님인 object1.data라는게 위의 this랑 동일한 뜻입니다.
근데 놀라운 사실은 그냥 this라는 뜻은 2번만 아시만 됩니다.
1번, 즉 "일반 함수 내에서 썼을 때 this는 window입니다"라는 정의는 굳이 외울 필요가 없습니다.
왜냐면 여러분이 2번 뜻을 잘 배우셨다면 1번도 자연스레 유추가 가능하니까요.
여러분이 함수나 변수를 대충 script태그 안에 만들었을 때, 함수나 변수는 그냥 만들어지는게 아닙니다.
방금 만든 함수)는 전역변수나 전역함수를 관리하기 위한 window라는 오브젝트에 자동으로 추가가됩니다.
왜 그렇냐고요?
그건 자바스크립트 만든 사람에게 물어보시기 바랍니다.
그래서 코드(1) 코드(2) 둘다 자바스크립트 입장에서 보면 똑같단 이야기입니다.
(2)문법은 window라는 오브젝트에 함수 자료를 추가하는 문법일 뿐입니다. 어려운거 없습니다.
아무튼 결론은 전역함수 만들거나 전역변수 만드시면 저렇게 window {오브젝트}안에 담긴다는 소리입니다.
우리가 일부러 하지 않아도 변수나 함수 쌩으로 만들면 자바스크립트가 자동으로 알아서 window안에 담습니다.
그럼 이제 function 문법의 동작원리 하나를 알았으니 다시 한번 this를 여기서 출력해봅시다.
여기서 this는 무슨 값이 나올까요?
this는 아까 2번에 의하면 내 메소드를 포함하고 있는 주인님 오브젝트를 출력시켜준댔죠?
함수()를 포함하고 있는 주인님 object가 무엇입니까?
바로 window객체 인 겁니다.
그래서 1번 : this를 함수안에서 썼을 땐 window가 나온다~ 라는 건 안외우셔도 되고
2번 : this는 오브젝트 내의 메소드(함수)에서 사용했을 때 메소드의 주인님 object를 출력해준다~
요것만 외우시면됩니다.
참고로 object안에 들어가는 함수들을 있어보이는 전문용어로 메소드(method)라고 칭합니다.
근데 난관이 있습니다. this의 얼탱이없는 3번 4번 뜻도 있기 때문입니다.
3. constructor안에서 쓰면 constructor로 새로생성되는 object를 뜻합니다.
자바스크립트에서 object를 비슷한걸 여러개 만들고 싶을 경우
object를 복사하는게 아니라 constructor라는걸 만들어서 사용합니다.
쉽게 말하면 constructor는 오브젝트 복사해서 생성해주는 기계입니다.
기계를 어떻게 만드는지 알아봅시다.
이게 기계 만드는 법입니다.
함수 문법을 이용해서 만든 후, 안에 this.어쩌구를 추가하시면 됩니다.
여기서의 this는 기계로부터 새로 생성될 object들을 의미합니다.
그럼 this.이름 = 'Kim'이건 무슨 뜻일까요?
새로생성되는 object의 이름 key값에 'Kim'이라는 value를 집어넣어주세요 라는 뜻입니다.
이건 참고로 알아두시면 좋은 기계에서 object뽑는 법입니다.
이렇게 new 키워드를 이용하면 새로운 object를 꺼낼 수 있습니다.
그리고 새로운 object {이름 : 'Kim'}이라는 값을 가지고 있습니다. (this라는 키워드 덕분에요)
4. eventlistener 안에서 쓰면 this는 e.currentTarget이라는 의미입니다.
이벤트리스너라는 문법 아시쥬?
여기서 this를 소환하는 이것은 바로 e.currentTarget이라는 뜻과 똑같은 의미입니다.
e.currentTarget은 지금 이벤트가 동작하는 곳을 뜻합니다.
매우 간단히 설명하면 지금 addEventListener 부착된 HTML 요소를 뜻한다고 보시면 됩니다.
이게 this의 마지막 뜻입니다.
case1. 이벤트리스너 안에서 콜백함수를 쓴다면 this는?
이벤트리스너 안에서 forEach() 라는 반복문을 사용했습니다.
forEach()반복문을 사용할 땐 안에 function(){} 콜백함수를 집어넣어서 사용하게 되어있습니다.
(*콜백함수는 그냥 함수 안에 파라미터역할로 들어가는 함수를 뜻합니다. 그게 다입니다)
하지만 솔직히 forEach감 무슨 역할을 하는지 모르셔도 이건 알 수 있습니다.
Q. 위 코드에서 this를 출력하면 무엇이 나올까요?
A. 지금까지 알아봤던 this의 1,2,3,4번 뜻을 대입해봅시다.
4번뜻에 의하면 eventListener안에서 쓴 건 아닙니다.
eventListener내부는 맞지만 그 안에서 function을 하나 더 만났기 때문에 의미가 변합니다.
3번뜻에 의하면 constructor는 아닌 것 같습니다.
실은 this의 1번이나 2번뜻이 맞습니다.
저렇게 쌩으로 있는 콜백함수는 그냥 일반함수랑 똑같기 때문에 window가 출력됩니다.
this의 값은 this가 어떤 함수안에 들어있는지만 잘 체크하시만 바로 아실 수 있습니다.
case2. object안에서 콜백함수를 쓴다면 this는?
이번엔 이런 코드를 쓴다고 해봅시다
object1이라는 object안에 이름들, 함수라는 자료를 각각 저장했습니다.
함수라는 자료안에 forEach반복문을 돌렸는데,
Q.그럼 여기 안에서의 this값을 출력하면 뭐가 나올까요?
역시 잘 대입을 해보시면 되겠습니다.
this값을 판단하실 땐 가장 가까이 있는 함수를 살펴보시면 됩니다.
forEach() 안에 있는 함수에 this가 들어있죠?
근데 이 함수는 무슨 뭐 특별한 역할을 하는 함수인가요?
아닙니다. 그냥 일반 함수일 뿐입니다.
그래서 이것도 window입니다.
자. 조금 정리를 해보자면
this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수(self-referencing variable)다. this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 따라 동적으로 결정된다.
함수 호출 방식 | this가 가리키는 값(this 바인딩) |
일반 함수로서 호출 | 전역 객체 |
메서드로서 호출 | 메서드를 호출한 객체(마침표 앞의 객체) |
생성자 함수로서 호출 | 생성자 함수가(미래에) 생성할 인스턴스 |
그래서 this값은 function을 만날 때마다 바뀔 수 있기 때문에
내가 원하는 this를 쓰기 힘든 경우가 있습니다.
그럴땐 함수를 arrow function으로 바꿔보시길 바랍니다.
자바스크립트 ES6문법 중,
function(){} 대신 쓸 수 있는 () =>{}이라는 arrow function 문법이 있습니다.
똑같이 함수 만드는 문법입니다.
이걸 쓰시면 함수 내부의 this값을 새로 바꿔주지 않기 때문에 this를 사용하실 때 유용합니다.
심심하면 사용하시길 바랍니다.(아니면 애초에 this 키워드를 쓰지 맙시다)
자세한 arrow function에 관한 내용은 다음 포스팅에서 보도록합시다.
출처 : 코딩애플의 매우쉽게 이해하는 JavaScript 객체지향 & ES6 신문법
'JavaScript > ES6' 카테고리의 다른 글
[ES6]Spread Operator 2. & apply, call함수 (0) | 2022.08.24 |
---|---|
[ES6]Spread Operator 1. (0) | 2022.08.24 |
[ES6]Template literals/Tagged literals (0) | 2022.08.24 |
[ES6]변수 연습문제 (0) | 2022.08.24 |
[ES6]Arrow function (0) | 2022.08.24 |