본문 바로가기

Javascript - this 키워드 본문

JavaScript

Javascript - this 키워드

개발자로 거듭나기 2023. 5. 30. 09:10
반응형

Javascript this

this

  • JavaScript에서 "this"는 현재 실행 중인 코드의 컨텍스트를 참조하는 특별한 키워드입니다. 이 컨텍스트는 주로 함수 또는 메소드가 호출되는 방법에 따라 결정됩니다.
  • this는 호출될 때 결정되며 호출될 때 this가 특정 객체에 바인딩된다고 합니다.

여러 상황에서의 this의 값

1. 브라우저 환경일 경우

  • 브라우저 콘솔에 this를 찍어보세요
console.log(this); // window

function whatIsThis() {
  console.log(this); // window
}

whatIsThis();

2. 엄격모드일 경우

"use strict";

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

whatIsThis(); // undefined

3. NodeJs 환경일 경우

  • node index.js 실행
console.log(this) // {}
console.log(this === module.exports); // true

function whatIsThis() {
  console.log(this === global); // true
}

const whatIsThisInArrow = () => {
  console.log(this === module.exports); // true
};

whatIsThis();
whatIsThisInArrow();
  • node 환경에서 this를 찍어보면 {} 이고, 이것은 module.exports 객체를 가리킨다고 합니다.
  • 또한, 함수 선언문에서의 this는 global을 가리킵니다.
  • 또한, 화살표함수에서의 this도 한단계 상위객체를 가리키기 때문에 module.exports 객체를 기리킵니다.

this가 대표적으로 바인딩 될 때

1. 기본 바인딩

  • 위의 <여러 상황에서의 this의 값> 항목과 동일합니다. this가 기본적으로 바인딩되는 규칙이죠
  • 기본적으로 브라우저 환경에서 window객체, 엄격모드일 때, undefined
  • 노드환경에서 전역코드에서는 module.exports, 함수 선언문 내부에서는 global을 가리킵니다.

2. 명시적 바인딩

  • 함수에 명시적으로 this에 해당하는 객체를 바인딩 합니다.

apply

function sayName(...args) {
  console.log(
    `Hi, my name is ${this.name}, I'm ${args[0]} and live in ${args[1]}`
  );
}

const person = {
  name: "tom",
};

// 추가로 배열로 인자를 줄 수 있습니다.
// Hi, my name is tom, I'm 15 and live in Seoul
sayName.apply(person, ["15", "Seoul"]);

call

function sayName(greeting) {
  console.log(greeting + ", " + this.name);
}

const person = {
  name: "tom",
};

// 첫번째 인자로 바인딩할 객체를 할당하고 그 후의 인자는 sayName의 인자로 들어갑니다.
sayName.call(person, "Hello"); // Hello, tom

bind

function sayName() {
  console.log(this.name);
}

const person = {
  name: "tom",
};

//
const tomBind = sayName.bind(person);
tomBind(); // tom

3. 암시적 바인딩

  • printMyName에서의 this는 본인을 호출한 person객체가 됩니다. 이를 암시적 바인딩이라고 합니다.
const person = {
  name: "tom",
  printMyName() {
    console.log(this.name);
  },
};

person.printMyName(); // tom

4. new 바인딩

  • 가장 강력한 바인딩으로써 new 키워드 뒤에 붙은 함수는 생성자 함수로서 동작하게 됩니다.
function Person(name) {
  this.name = name;
}

const tom = new Person("tom");
console.log(tom.name); // tom
  • 1 → 2 → 3 → 4번으로 갈 수록 this 바인딩의 우선순위가 높습니다.
반응형

암시적 바인딩이 풀리는 경우

1. 함수가 일반적인 방식으로 호출될 때 (자신을 바인딩하는 obj가 없을 때)

  • 한단계만 이동해도 this 바인딩이 풀려버린다.
const person = {
  name: "tom",
  sayName() {
    console.log(this.name);
  },
};

person.sayName(); // tom

const sayNameFunc = person.sayName;
sayNameFunc(); // undefined (암시적 바인딩이 풀림)

2. setTimeout 내부에서의 호출

const obj = {
  message: "Hello",
  printMessage() {
    console.log(this.message);
  },
};

setTimeout(obj.printMessage, 1000); // undefined (암시적 바인딩이 풀림)
  • 아래와 같이 바꾸면 바인딩을 유지키실 수 있다.
  • setTimeout 내부의 화살표함수가 상위의 문맥의 this를 참조하면서 this.message를 출력할 수 있다.
const obj = {
  message: "Hello",
  printMessage(sec) {
    setTimeout(() => {
      console.log(this.message);
    }, sec);
  },
};

obj.printMessage(1000);

3. 이벤트 핸들러에서의 함수 호출

  • addEventListener 에서 콜백의 this는 addEventListener를 발화시킨 button 컴포넌트 입니다.
const button = document.querySelector("button");

const obj = {
  message: "Hello",
  printMessage() {
    console.log(this.message); // undefined
        console.log(this) // 버튼이 출력된다
  },
};

button.addEventListener("click", obj.printMessage); // (암시적 바인딩이 풀림)

화살표 함수를 이용해서 상위 this 문맥을 유지하기

  • sayHello()의 return문 안의 함수를 화살표함수로 코딩함으로써, this는 Person 클래스를 가리킬 수 있게 됩니다.
class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    return () => {
      console.log(`Hello, ${this.name}!`);
    };
  }
}

const person = new Person("Alice");
const helloFunc = person.sayHello();
helloFunc(); // "Hello, Alice!" 출력
반응형
Comments