모던 자바스크립트 핵심 가이드 #1

nearworld·2023년 8월 17일
0

프로그래밍 독서

목록 보기
2/3

use strict 사용하지 않을때

function foo() {
  console.log(this);
}

foo();

결과:

Window { ... }

use strict 사용할 때

'use strict';
function foo() {
  console.log(this);
}

foo();

결과:

undefined

ES6(ES2015) Module

function foo() {
  console.log(this);
}

foo();

결과:

undefined

this 키워드의 바인딩은 런타임에서 발생한다.

const device = {
  type: 'computer',
  printType: function () {
    console.log(this.type);
  }
};

const justPrint = device.printType;
justPrint();

결과:

Uncaught TypeError: Cannot read properties of undefined (reading 'type')

justPrint() 함수 호출은 런타임에서 일어납니다.
이 런타임때 this 키워드의 바인딩 작업이 이루어집니다.

출처: In most cases, the value of this is determined by how a function is called (runtime binding).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

  1. use strict 를 사용하지 않을때,
    그러나 함수 호출 시점에서 이 함수의 부모 스코프는 전역 스코프입니다.
    전역 스코프에서 thisWindow 객체입니다.
    그러므로 thisWindow를 가리킵니다.

  2. use strict 를 사용할 때,
    똑같이 함수 호출 시점에서 함수의 부모 스코프는 전역 스코프입니다.
    하지만 이때 this는 함수 스코프안에 있습니다.
    그리고 use strict 모드라 외부 스코프를 참조하지 않습니다.
    그래서 undefined입니다.

const device = {
  type: 'computer',
  printType: function () {
    console.log(this.type);
  }
};

device.printType();

결과:

computer

printType 은 여기서 '메서드'입니다.
printType 함수의 부모 스코프가 객체라는 의미가 됩니다.
함수 호출 시점에서 printType 은 메서드입니다.
그래서 this 키워드가 부모 스코프에 해당하는 객체에 바인딩됩니다.

bind를 사용하여 수동으로 참조 대상 지정

const device = {
  type: 'computer',
  printType: function () {
    console.log(this.type);
  }
};

const justPrint = device.printType;
const bindJustPrint = justPrint.bind(device);
bindJustPrint();

출력:

{
	type: 'computer',
    printType: function () {
    	console.log(this.type); 
    }
}

device 객체를 참조하게 했음을 알 수 있습니다.

제가 이 this 키워드의 작동 방식에 대해 공부하면서 헷갈렸던 부분이 있습니다.
바로 렉시컬 스코프입니다.

자바스크립트의 스코프는 렉시컬 스코프입니다.
그래서 부모 자식 스코프 관계가 함수가 선언되는 위치를 기준으로 결정됩니다.
런타임에서 실행될때 결정되지 않습니다.

그래서 this 키워드도 그럴거라 생각했습니다만
this 키워드는 런타임때 스코프 참조 대상이 정해집니다.

저는 이 부분을 쉽게 기억하기 위해서 아래와 같이 생각하기로 했습니다.

자바스크립트에서 스코프 관계는 정적이다.
자바스크립트에서 this 바인딩은 동적이다.

profile
깃허브: https://github.com/nearworld

1개의 댓글

comment-user-thumbnail
2023년 8월 17일

즐겁게 읽었습니다. 유용한 정보 감사합니다.

답글 달기