(JS) This

Mirrer·2022년 5월 3일
0

JavaScript

목록 보기
22/24
post-thumbnail

This

자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수

this는 자신의 속성을 참조하는 자기 참조 변수로 자바스크립트에서 this는 문맥에 따라 가리키는 대상이 달리진다.

타언어와는 다르게 자바스크립트는 런타임 상에서 this바인딩이 동적으로 결정되어 상황마다 다른 대상을 가르킨다.

이렇게 특정 객체마다 this를 묶어놓은 것을 this바인딩이라 한다.


문맥에서의 this

  • 글로벌 컨텍스트this : Window
console.log(this);
 // Window {window: Window, self: Window, document: document, name: '', location: Location, …}

console.log(this.setTimeout);
// ƒ setTimeout() { [native code] }

console.log(setTimeout);
// ƒ setTimeout() { [native code] }

console.log(globalThis);
// Window {window: Window, self: Window, document: document, name: '', location: Location, …}
  • 생성자 함수, 클래스(엄격 모드)this : 앞으로 생설될 인스턴스
// 생성자 함수
function Cat(name) {
  this.name = name;
  this.printName = function () {
    console.log(this.name);
  }
}

const cat1 = new Cat('냐옹');
const cat2 = new Cat('미야옹');
cat1.printName(); // 냐옹
cat2.printName(); // 미야옹
// 클래스 (엄격 모드)
'use strict';

function Cat(name) {
  this.name = name;
  this.printName = function () {
    console.log(this.name);
  }
}

const cat1 = new Cat('냐옹');
const cat2 = new Cat('미야옹');
cat1.printName(); // 냐옹
cat2.printName(); // 미야옹
  • 함수 내부this : globalThis, undefined, Window
// 일반 함수
function fun() {
  console.log(this);
}
fun(); // Object [global] {....}
// 일반 함수 (엄격 모드)
'use strict';

function fun() {
  console.log(this);
}
fun(); // undefined
// 브라우저
function fun() {
  console.log(this);
}
fun(); // Window {window: Window, self: Window, document: document, name: '', location: Location, …}

This의 동적, 정적 바인딩

동적 바인딩

타 객체지향 프로그래밍 언어(자바, C++...등등)의 this는 항상 자신의 인스턴스를 가르킨다.

정적으로 인스턴스가 만들어지는 시점에 this가 결정된다.

하지만 자바스크립트에서는 누가 호출하냐에 따라서 this가 달라진다. 이는 호출하는 사람(caller)에 의해 this가 동적으로 결정된다고 할 수 있다.

function Cat(name) {
  this.name = name;
  this.printName = function () {
    console.log(`고양이의 이름을 출력한다: ${this.name}`);
  }
}

function Dog(name) {
  this.name = name;
  this.printName = function () {
    console.log(`강아지의 이름을 출력한다: ${this.name}`);
  }
}

const cat = new Cat('냐옹');
const dog = new Dog('멍멍');

dog.printName = cat.printName;
dog.printName(); // 고양이의 이름을 출력한다: 멍멍
cat.printName(); // 고양이의 이름을 출력한다: 냐옹

만약 호출하는 객체없이 함수를 실행하면 undefined이 출력된다.

function Cat(name) {
  this.name = name;
  this.printName = function () {
    console.log(`고양이의 이름을 출력한다: ${this.name}`);
  }
}

function Dog(name) {
  this.name = name;
  this.printName = function () {
    console.log(`강아지의 이름을 출력한다: ${this.name}`);
  }
}

const cat = new Cat('냐옹');
const dog = new Dog('멍멍');

function printOnMonitor(printName) {
  console.log('모니터를 준비한 뒤 전달된 콜백함수를 실행!');
  // 호출하는 객체가 없기 때문에 this는 undefined가 할당
  // object.printName();
  printName();
}
printOnMonitor(cat.printName); // 고양이의 이름을 출력한다: undefined

정적 바인딩

자바스크립트에서는 동적 바인딩뿐만 아니라 정적 바인딩을 하는 방법이 존재한다.

  • bind : this수동적으로 바인딩
function Cat(name) {
  this.name = name;
  this.printName = function () {
    console.log(`고양이의 이름을 출력한다: ${this.name}`);
  }
  this.printName = this.printName.bind(this);
}

function Dog(name) {
  this.name = name;
  this.printName = function () {
    console.log(`강아지의 이름을 출력한다: ${this.name}`);
  }
}

const cat = new Cat('냐옹');
const dog = new Dog('멍멍');

dog.printName = cat.printName;
dog.printName(); // 고양이의 이름을 출력한다: 냐옹
cat.printName(); // 고양이의 이름을 출력한다: 냐옹
  • arrow function : 화살표 함수는 렉시컬환경의 this를 기억, 화살표 함수 밖에서 제일 근접한 스코프의 this를 가르킨다.
function Cat(name) {
  this.name = name;
  this.printName = () => {
    console.log(`고양이의 이름을 출력한다: ${this.name}`);
  }
}

function Dog(name) {
  this.name = name;
  this.printName = function () {
    console.log(`강아지의 이름을 출력한다: ${this.name}`);
  }
}

const cat = new Cat('냐옹');
const dog = new Dog('멍멍');

dog.printName = cat.printName;
dog.printName(); // 고양이의 이름을 출력한다: 냐옹
cat.printName(); // 고양이의 이름을 출력한다: 냐옹

Arrow Function

전통적인 함수표현(function)의 간편한 대안

화살표함수(arrow function)는 기존의 함수보다 문법이 깔끔하고, 생성자 함수로도 사용이 불가능하여 무거운 프로토타입을 생성하지 않는다.

그리고 this에 대한 바인딩이 정적으로 결정된다. 이 때 결정된 this는 함수에서 제일 근접한 상위 스코프의 정적으로 바인딩 된다.

const cat = {
  name: 'Cat',  
  play () {
    console.log('냐옹');
  },
};

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

cat.printArrow = printArrow;
cat.printArrow();  // {} => cat객체를 감싸고 있는 전역객체를 출력

참고 자료

this - JavaScript | MDN
화살표 함수 - JavaScript
모던 자바스크립트 Deep Dive
모던 JavaScript 튜토리얼

profile
memories Of A front-end web developer

0개의 댓글