지금의 회사에서는 매주 수요일 마다 개발 내용으로 주간 스터디를 진행하고 있다. (안바쁜 달 한정 매 주)
(개발에 관련한 내용이라면 아무 얘기나 가능~!)
스터디라고 해서 거창한건 없고, 한 주에 1명씩 돌아가면서 정해진 주제를 가지고 간단하게 팀원에게 소개하는 자리인데,
이번 주는 내 차례였다.
내가 맡은 주제는 자바스크립트의 옵셔널 체이닝
근데 왜 이 글의 제목은 this 인 것인가...
왜냐면... 내가 설명한 부분에서 잘못된게 있었다.
내가 맡았던 옵셔널 체이닝 부분 포스팅이다.
내용은 이러했다.
const obj = {
value: 1,
increment: () => {
this.value += 1;
return this;
},
add: (number) => {
this.value += number;
return this;
},
close: () => {
console.log(this.value)
}
}
// 체이닝 호출
obj.increment().add(2).close(); // return 4
// 체이닝을 하지 않으면 아래와 같이 호출하여 사용
obj.increment()
obj.add(2)
obj.close() // return 4
this
💡 자바스크립트에서의 this 함수의 현재 실행 문맥 (context) 자바스크립트에서 함수를 호출할 때 기존 매개변수로 전달되는 인자값에 더해 arguments 객체 및 this 인자가 함수 내부로 암묵적으로 전달됩니다.
- 객체의 메소드 호출할 때 this 바인딩
- 객체의 프로퍼티가 함수일 경우, 함수 내부에서 사용된 this는 해당 함수를 호출한 객체로 바인딩 됩니다.
const obj = { name: '전다훈', getName: function (){ console.log(this === obj) // return true console.log(this.name) // return "전다훈" } }
- 함수를 호출할 때 this 바인딩
- 함수를 호출할 경우, 해당 함수에서 사용된 this는 전역 객체에 바인딩 됩니다.
- 브라우저에서의 전역 객체는 window
const str = "Hello World"; console.log(window.str) // "Hello World" const testFunction = function () { console.log(this.str) // "Hello World" }
이 포스팅을 토대로 팀장님께서 질문을 하셨는데
Arrow Function 에서도 저 글처럼 동작하나요?
저렇게 Arrow Function으로 생성한 메소드의 this 도 자신 객체를 가르키고 있나요??
우물쭈물 하면서 내가 작성한 글을 읽어보며 코드를 실행시켜봤다.
왜지.. 왜일까..?
위의 2번을 보면 함수를 호출할 경우, 해당 함수에서 사용된 this는 전역 객체에 바인딩(window) 된다고 했다.
function javascriptThis() {
console.log('THIS!')
}
console.log(window)
콘솔을 확인해보면 window 객체 내의 global 에 방금 선언한 javascriptThis() 함수가 존재하는 것을 알 수 있다.
객체 안에서 사용한 함수의 this 는 어떨까??
1 번 예제대로 전역이 아닌 자신 객체를 가르키고 있다.
내가 첫 예제로 보였던 객체 내에서 arrow function 을 사용하면 어떻게 될까??
window 객체를 가르키고 있다. 그렇기 때문에 예제에서 return 값을 표시했던 부분들이 잘못되었다.
그렇다면 왜 일반 함수와 다르게 화살표 함수의 경우에는 this가 전역을 가르키고 있을까?
일반 함수의 경우 함수를 선언할 때 this가 바인딩 되는게 아닌, 어떻게 호출되었는지에 따라서 this에 바인딩할 객체가 동적으로 결정된다.
하지만, 화살표 함수의 경우에는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정된다.
💡 화살표 함수의 this는 언제나 상위 스코프의 this를 가르키는데 이를 Lexical this 라고 한다.
function lexicalThis () { // return Arrow Function return (answer) => { console.log(this.answer); // this 는 상위 스코프인 lexicalThis() 에 상속된다. } } const obj = { a: 2 }; const obj2 = { a: 3 }; const bar = lexicalThis.call(obj); bar.call(obj2) // return 2
하지만 리턴된 화살표 함수를 다음 bar를 bar.call(obj2)로 실행하여 obj2 를 this로 바인딩 하면 3이 나올 것 같지만 나오지 않는다.
lexicalThis() 함수는 call() 메소드로 obj 에 this가 바인딩 되므로 bar 역시 obj에 바인딩 된다.
화살표 함수는 call(), bind() 와 같은 메소드로는 바인딩을 할 수 없다.
따라서 bar.call(obj2)의 경우 this가 바인딩 되지 않아 상위 스코프인 lexicalThis() 를 상속 받아 2를 리턴하게 된다.
따라서 obj가 아닌 그 상위 스코프인 window 객체를 가르키고 있는 것!!!
'개발노트 > JavaScript' 카테고리의 다른 글
Potentially invalid reference access to a class field via 'this.' of a nested function (0) | 2023.05.19 |
---|---|
[JavaScript] Get, Set (0) | 2023.04.06 |
[JavaScript] Promise (async/await) (0) | 2022.09.14 |
[JavaScript] filter ( ) (0) | 2022.01.17 |
[JavaScript] 자바스크립트로 Ajax 구현 (0) | 2021.09.28 |