인프런 커뮤니티 질문&답변

taylous님의 프로필 이미지
taylous

작성한 질문수

모던 자바스크립트(ES6+) 기본

Arrow Function 에서 Scope 관련 질문이 있습니다.

해결된 질문

작성

·

190

1


안녕하세요.

예전에 이해하고 넘어갔으나 다시 잘 안떠올라서 돌아왔는데, 또 뭔가 새롭습니다.

몇 가지 혼란스러운 부분이 있어 질문하고자 합니다.

 

var value = 1000;

function Node(value) {
  this.value = value;
}

Node.prototype.getValueByArrow = () => {
  console.log("this: ", this);
  console.log(this.value);
};

Node.prototype.getValueByFunc = function () {
  console.log("this: ", this);
  console.log(this.value);

  let hello = "hi";

  const hi = () => {
    console.log(this);
    console.log(hello);
  };
  hi();
};

Node.prototype.getValueTest = function () {
  console.log("this: ", this);
  console.log(this.value);

  const arrowTest = () => {
    console.log("arrow this in func: ", this);
  };
  arrowTest();
};

new Node(100).getValueByArrow();
new Node(300).getValueByFunc();
new Node(300).getValueTest();

1️⃣ Arrow Function의 this는 Arrow Function이 속해있는 object의 ThisBindingComponent를 따라가는 건가요?

위의 코드로 테스트 해보니, 'getValueTest'의 this와 안에 있는 'arrowTest'의 this가 같음을 확인했습니다. 그렇다면 ThisBindingComponent를 따라간다고 해석해도 될까요?

2️⃣ 정리하자면, "일반함수(function name() {...})의 this는 호출할 때 앞의 object가 scope로 되고(ex: obj.name()), Arrow Function은 자기가 속해있는 object의 this(ThisBindingComponent)를 참조한다." 이렇게 해석해도 될까요?

3️⃣ this는 함수가 호출될 때 결정이 된다고 알고있습니다. 그렇다면 Arrow Function은 Engine에 의해 만들어질 때, 정해진다고 봐도 될까요?

답변 주시면 감사하겠습니다.

답변 5

1

김영보님의 프로필 이미지
김영보
지식공유자

이해가 되었다니 다행입니다. 그렇게 찾아 테스트하고  검증하는 것이 매우 중요합니다. 좋은 모습입니다. 그리고 예의에 고맙게 생각하지만 교수 아닙니다. 호칭에 신경 쓰지말고 강사로 불러도 됩니다. 

1

taylous님의 프로필 이미지
taylous
질문자


답변 너무 감사합니다.

교수님께서 올려주신 답변을 보고 처음에는 이해가 안되었는데 MDN에 직접 찾아보고 계속 읽다보니 이해가 되었습니다.

늦은 시간에도 자세한 답변 주셔서 감사합니다.

혹시나 이 글을 보는 다른 분들을 위해 참고한 URL 올려두겠습니다.

📌 참고한 URL>

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/%EC%95%A0%EB%A1%9C%EC%9A%B0_%ED%8E%91%EC%85%98

1

김영보님의 프로필 이미지
김영보
지식공유자

Arrow Function은 자기가 속해있는 Object의 this를 참조한다.
==> 자기가 속해 있는 Object를 this로 참조한다. 
function 키워드의 Function은 자기가 속한 오브젝트를 this로 참조합니다. 아래 코드 1)번의 this.point에서 this는 book 오브젝틀 참조합니다. 
한편, Arrow Function은 주변 환경에 따라 다릅니다.
아래 코드 2)번의 (value) => {this.point}에서 this는 book 오브젝트를 참조하지만, 3)번의 getPoint: () => {this.point}에서 this는 Window 오브젝트를 참조합니다.
속한 개념으로 보면  (value) => {this.point}는 forEach(){}에 속하며, getPoint: () => {this.point}는 book 오브젝트에 속합니다. 그런데 전자의 this.point는 book를 참조하고 후자의 this.point는 Window 오브젝트를 참조합니다.

const book = {
  point: 100,
  addPoint(){
    // 1) this가 book 참조, 100출력
    console.log(this.point);
    [10, 20].forEach((value) => {
      // 2) this가 book 참조, 110, 120출력
      console.log(this.point + value);
    })
  },
  getPoint: () => {
    // 3) this가 Wondow 오브젝트 참조, undefined 출력
    console.log(this.point);
  }
};
book.addPoint();
book.getPoint();

1

김영보님의 프로필 이미지
김영보
지식공유자

생각을 많이 한 질문입니다. 논리적으로 접근한 질문, 좋습니다.

[2] 전반적으로 내용이 맞습니다.
호출할 때 앞의 object가 scope로 되고 ==> 호출할 때 앞의 object를 함수에서 this로 참조하게 되고
자바스크립트는 정적 스코프로 function 키워드를 만나 Function 오브젝트를 생성할 때 스코프가 결정됩니다. 스코프와 this 참조는 차이가 있습니다. 스코프가 더 범위가 넓으며, this와 스코프가 같을 때도 있지만 다를 때로 있습니다.
prototype에 연결된 Arrow function은 인스턴스를 this로 참조하지 않으며, 이것은 prototype에 연결하는 목적에 어긋납니다.

[3] function 키워드를 만나서 Function 오브젝트를 생성할 때 this 참조가 결정된다고도 할 수 있습니다. Arrow Function이 그렇습니다. call()과 apply()는 결정되어 있는 this 참조를 바꾸려는 의도입니다.

두 가지를 반영하여 정리하면 논리가 정리될 것 같습니다. 

0

taylous님의 프로필 이미지
taylous
질문자


답변 정말 감사합니다.

그런데 한 부분이 아직 정리가 되지 않는듯 하여 다시 한 번 질문드립니다.

📌 prototype에 연결된 Arrow function은 인스턴스를 this로 참조하지 않으며, 이것은 prototype에 연결하는 목적에 어긋납니다.
라고 말씀해주셨는데 "Arrow Function은 자기가 속해있는 Object의 this를 참조한다."라는 말은 틀린 건가요?

taylous님의 프로필 이미지
taylous

작성한 질문수

질문하기