[JS] this

이의섭·2021년 12월 27일
0
post-thumbnail

자바스크립트를 배우면서 "this"에 대해 많이 어려워하고 아직도 잘 모르고있는것 같습니다. 우리는 이 "this"를 객체의 메서드에서 자주 볼 수 있습니다.

객체 메서드 안에서 this

let user = {
    name: "Uiseop",
    born: 1997,
    sayHi() {
    	console.log(this.name); *(1)*
        // console.log(user.name); // 동일하다
    }
};

user.sayHi(); // Uiseop

메서드 내부에서 "this"키워드를 사용하면 객체에 접근할 수 있습니다.
이때 this는 user.sayHi();에서 user를 가리킵니다. 메서드의 점(.) 앞을 가리키고 있는 것 입니다. 정확히는 메스드를 호출할 때 사용되는 객체를 나타냅니다.

이때 위의 코드 (1)부분에서 "this"를 사용하지 않고 외부 변수인 user를 참조하는, "this"user라고 변경해도 같은 결과가 나타납니다.

이게 가능한 이유는 함수를 실행하거나, 코드블럭을 진입할 때, 스크립트를 실행할 때 자바스크립트가 생성하는 렉시컬 환경(Lexical Enviroment) 을 먼저 이해하시면 좋겠습니다.

다시 돌아와서 그럼 외부 변수인 user를 사용하지 않고 이해하기도 어렵운 "this"를 사용할까요?

this를 사용하는 이유

외부 변수인 user로 객체안의 프로퍼티를 접근하려고 하면 예상치 못한 에러가 발생할 수 있습니다. 가령 객체 user를 다른 변수에 할당(admin=user)하고, user를 name이라는 프로퍼티가 없는(user=null) 다른 값으로 덮어썼다고 가정합니다.

그러면 admin이 참조하는 객체의 sayHi()메서드는 user.name을 호출하고 있는데 user에는 name이라는 프로퍼티가 없기때문에 에러가 나고, 에러를 해결하기 위해서는 같은 코드를 또 귀찮게 작성해야한다는 문제가 발생합니다.

하지만 애초에 user.name대신 this.name을 인수로 받았다면 중복되는 코드를 작성하는 낭비를 줄일 수 있습니다.

자유로운 this

자바스크립트에서 모든 함수에서 "this"를 사용할 수 있습니다. 왜냐하면 "this"런타임에 결정되기 때문입니다. 컨텍스트에 따라 달라지죠. 따라서 동일한 함수라도 다른 객체에서 호출했다면 "this"가 참조하는 값이 달라집니다.

"this"런타임에 결정되면 좋은 점도 있고 나쁜 점도 있습니다. 함수를 하나만 만들어서 여러 객체에서 재사용할 수 있다는 것은 분명한 장점이지만, 이러한 유연함이 저한테는 너무 어렵게 느껴지는게 단점입니다.

그럼 이 결과는 뭘까요?

정답

비엄격모드 undefined

엄격모드 Error: Cannot read property 'name' of undefined

에러가 발생하는 이유는 this값을 설정할 땐 객체 정의가 사용되지 않기 때문입니다. this은 호출 시점에 결정됩니다.

위 코드에서 makeUser()thisundefined입니다. 객체의 메서드로 사용되지 않았기 때문(참조하는 객체가 없음)입니다. this은 함수 내의 코드 블록에 상관없이 모두 함수의 현재 this값을 가져오기 문에 ref: this도 마찬가지로 undefined를 가져옵니다.

에러가 발생하지 않게 하려면 ref또한 메서드가 되어 객체를 참조할 수 있으면 됩니다.

this가 없는 화살표 함수

바로 앞에서 모든 함수에서 "this"를 사용할 수 있다고 했는데 화살표 함수에선 못쓴다?

화살표 함수는 일반 함수와는 달리 고유한"this"를 가지지 않습니다. 화살표 함수에서 "this"를 참조하면, 화살표 함수가 아닌 외부의 일반 함수에서 "this"값을 가져옵니다.

일반 함수 sayHi()의 "this"는 user를 가리키고 있고, 화살표 함수인 arrow 함수는 외부 함수의 "this"인 user를 참조하고 있기 때문에 결과가 user.name이 나오는것을 확인할 수 있습니다.

💬요약

  • 모든 함수에서는 "this"를 사용할 수 있습니다.
  • 객체안의 메서드는 "this"를 통해 현재 객체에 접근할 수 있습니다.
  • 함수를 선언할 때 "this"를 사용할 수 없습니다. 다만, 함수가 호출되기 전까지 "this"엔 값이 할당되지 않습니다.
  • 별개의 "this"가 만들어지는 건 원하지 않고, 외부 컨텍스트에 있는 "this"를 사용하고 싶을 경우 화살표 함수가 유용합니다.
profile
사용자 중심 생각하는 프론트엔드 개발자가 되고 싶은..

0개의 댓글