개발노트/JavaScript

[JavaScript] this

Dahoon06 2023. 1. 27. 18:06
728x90
반응형

지금의 회사에서는 매주 수요일 마다 개발 내용으로 주간 스터디를 진행하고 있다. (안바쁜 달 한정 매 주)

(개발에 관련한 내용이라면 아무 얘기나 가능~!)

스터디라고 해서 거창한건 없고, 한 주에 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 인자가 함수 내부로 암묵적으로 전달됩니다.

  1. 객체의 메소드 호출할 때 this 바인딩
    • 객체의 프로퍼티가 함수일 경우, 함수 내부에서 사용된 this는 해당 함수를 호출한 객체로 바인딩 됩니다.
     const obj = {
         name: '전다훈',
         getName: function (){
             console.log(this === obj) // return true
             console.log(this.name)    // return "전다훈"
         }
     }
    
  2. 함수를 호출할 때 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 도 자신 객체를 가르키고 있나요??

 

우물쭈물 하면서 내가 작성한 글을 읽어보며 코드를 실행시켜봤다.

 

당당히 자신 obj 가 아닌 window를 가르키고 있었다.

 

왜지.. 왜일까..?

위의 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​


lexicalThis() 함수는 call() 메소드로 obj 에 this가 바인딩 되므로 bar 역시 obj에 바인딩 된다.

하지만 리턴된 화살표 함수를 다음 bar를 bar.call(obj2)로 실행하여 obj2 를 this로 바인딩 하면 3이 나올 것 같지만 나오지 않는다.
화살표 함수는 call(), bind() 와 같은 메소드로는 바인딩을 할 수 없다.

따라서 bar.call(obj2)의 경우 this가 바인딩 되지 않아 상위 스코프인 lexicalThis() 를 상속 받아 2를 리턴하게 된다.

 

따라서 obj가 아닌 그 상위 스코프인 window 객체를 가르키고 있는 것!!!

728x90
반응형