자바스크립트 - This와 스코프

LUCAS·2022년 10월 5일
1

최근에 면접을 보면서 This에 대한 심화 질문이 나왔다.

문서에도 몇 번 적었던지라, 자신있게 대답했는데 아뿔싸 완벽하게 이해하지못해 많이 헤매었다.

일단 This가 Javascript에서 어떻게 동작하는지 알아보자.

Javascript에서 This는 호출 방식에 따라 참조되는 값이 달라진다.

1. Object 메소드에서의 This

Object Method 형태로 this를 호출하면, this는 자신의 객체를 참조하게 됩니다.

예제 1

const howAreYouToday = {
  woowak: 'good',
  getProperties: function () {
    console.log(this)  // { woowak: 'good', getProperties: [Function] }
  }
}

예제 2 - 자신이 속해있는 객체에 대해서만 참조한다.

const howAreYouToday = {
  woowak: 'good',
  getProperties: function () {
    console.log(this)  // { woowak: 'good', getProperties: [Function] }
  },
  haku: {
      mitsune: 'haku',
      getProperties: function () {
        console.log(this)  // { mitsune: 'haku', getProperties: [Function] }
      },
  }
}

2. 함수 선언문에서의 This

함수 선언문에서 this를 호출하면, this는 global을 참조하게 됩니다.

예제 1

function howAreYouToday() {
  console.log(this) // global
}

예제 2 - 정말로 다양하게 호출해 보아도 위치에 상관없이 global을 참조한다.

// 1. Arrow Function 안에 IIFE+
const howAreYouToday = () => {
  (function () {
      (function () {
          console.log(this)  // global
      })()
  })()
}

// 2. Object Method를 통한 호출
const howAreYouToday = {
  getThisToInnerFunc: function () {
    function inner() {
      console.log(this)  // global
	}
    inner()
  }
}

console.log(howAreYouToday.getThisToInnerFunc())

정말 알잘딱하다!

3. new 키워드

new 키워드로 선언된 인스턴스를 호출하면, this는 생성자를 참조하게 됩니다.

예제 1

function howAreYouToday (helpful) {
  this.helpful = helpful
  console.log(this.helpful)  // { Слава: 'Україні!' }
}

const instance = new howAreYouToday({ Слава: 'Україні!' })

4. Function.prototype.call, apply

Function Prototype 함수를 통해 this를 전달할 수 있다.

예제 1 (Function.prototype.call)

function howAreYouToday () {
  console.log(this)  // { Слава: 'Україні!' }
}

howAreYouToday.call({ Слава: 'Україні!' })

예제 2 (Function.prototype.apply)

function howAreYouToday () {
  console.log(this)  // { Слава: 'Україні!' }
}

howAreYouToday.apply({ Слава: 'Україні!' })

Q. 오잉? 둘 다 똑같은데 그럼 둘의 차이점은 뭐야?

A. 인자로 넘기는 방식이 다릅니다.

call의 경우 comma로 구분해서 인자로 넘깁니다.

invokeCall(thisObj, argument1, argument2, argument3...)

apply의 경우 배열의 형태로 인자를 넘깁니다.

invokeApply(thisObj, [argument1, argument2, argument3...])
profile
안녕하세요! FE개발자 최근원입니다.

0개의 댓글