chatGPT로 뽑은 this 이미지

This?

자바스크립트에서 가장 많이 오해되는 키워드, this.
단어는 짧지만 동작은 상황에 따라 달라진다.
이번 글에서는 this의 개념을 간단한 예제와 함께 정리해보고자 합니다.

 

먼저 this는 함수가 호출되는 방식에 따라 this에 바인딩이 동적으로 결정된다.

*바인딩 : 식별자와 값을 연결하는 과정

 

1. 전역공간의 this

console.log(this) // window 객체

전역공간에서 this는 전역 객체를 가리킨다. node.js 환경에서는 global

 

 

2. 메서드 내부에서의 this

let obj = {
	fooA : function () { console.log(this); },
    inner : {
    	fooB : function () { console.log(this); }
    }
}

obj.fooA()
obj.inner.fooB()

메서드 내부 this 콘솔

this에는 호출한 주체 정보가 있는데 호출 주체는 바로 함수명 앞에 객체가 된다.

점 앞에 명시된 객체가 곧 this가 된다.

(ex. obj.fooA()는 obj가 this가 되고 obj.inner.fooB()는 obj.inner가 this가 된다)

 

 

3. 함수 내부에서의 this

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

showThis(); // 브라우저 환경에서는 window, Node.js에서는 global

함수에서의 this는 전역 객체를 가리킨다.

 

3-1. 메서드 내부에서의 중첩 함수 호출

const person = {
  name: "Jane",
  greet() {
    function inner() {
      console.log(this.name);
      console.log(this);
    }
    inner(); // 여기서 inner 함수 호출
  },
};

person.greet(); // undefined (또는 브라우저에선 빈 문자열), window 객체

메서드 내부의 inner()함수는 함수로서 호출하였다.

그렇기에 this.name은 전역에서의 name값이기에 빈문자열이 되고 this는 전역 객체가 된다.

 

함수 호출에 따른 this를 객체로 가리키는 방법

const obj = {
  name: 'Alice',
  sayHi: function () {
  
    const self = this; // 여기서 self에 this를 할당
    function inner() {
      console.log('Hi, ' + self.name);
    }

    inner();
  }
};

obj.sayHi(); // Hi, Alice

함수 밖에서 self 변수에 this를 할당하여 inner 함수 내부에서 self를 사용하게 되면 결국 obj를 가리키게 된다.

따라서 inner() 라는 함수로 호출하게 되어도 함수 밖에서 this를 가져왔기 때문에 전역 객체를 가리키는 상황은 발생하지 않게 된다.

요 방법은 ES5 문법의 방법이다.

 

또 다른 방법으로 화살표함수 사용법. (ES6 문법)

const obj = {
  name: 'Alice',
  sayHi: function () {
    const inner = () => {
      console.log('Hi, ' + this.name);
    };

    inner();
  }
};

obj.sayHi(); // Hi, Alice

화살표함수의 경우 정의된 시점의 외부 실행 컨텍스트 this를 그대로 사용한다.

화살표 함수는 실행 컨테스트를 만들 때 this 바인딩을 하지 않는다.

대신 정의된 시점의 스코프 체인에서 가장 가까운 함수의 this를 그대로 사용한다.

 

 

4. 콜백 함수 호출 시 그 함수 내부의 this

     const obj = {
        name: "Kim",
        hobbies: ["reading", "tennis"],

        showThisInSetTimeout: function () {
          setTimeout(function () {
            console.log("setTimeout (일반 함수):", this.name); // window 객체 (전역 객체)
          }, 500);

          setTimeout(() => {
            console.log("setTimeout (화살표 함수):", this.name); // obj 객체 this.name은 Kim
          }, 1000);
        },

        showThisInForEach: function () {
          this.hobbies.forEach(function (hobby) {
            console.log("forEach (일반 함수):", this.name + " likes " + hobby); // this.name은 빈 값을 가짐 (브라우저)
          });

          this.hobbies.forEach((hobby) => {
            console.log("forEach (화살표 함수):", this.name + " likes " + hobby); // 화살표함수는 this.name이 Kim값을 가짐
          });
        },

        showThisInEventListener: function () {
          const btn = document.getElementById("myBtn");

          // 일반 함수
          btn.addEventListener("click", function () {
            console.log("addEventListener (일반 함수):", this); // this → 버튼 요소
          });

          // 화살표 함수
          btn.addEventListener("click", (event) => {
            console.log("addEventListener (화살표 함수):", this); // this → obj
          });
        }
      };

      obj.showThisInSetTimeout();
      obj.showThisInForEach();
      obj.showThisInEventListener();

 

 

 

5. 생성자 함수 내부의 this

생성자 함수는 어떤 공통된 성질을 지니는 객체를 생성하는데 사용하는 함수이다.

객체지향 언어에서는 생성자를 클래스, 클래스를 통해 만들어진 객체를 인스턴스라고 한다.

new 명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작하게 된다.

 

생성자 함수 내부에서의 this는 만들어진 인스턴스 자신이 된다.

function Person(name, age) {
  this.name = name;
  this.age = age;

  this.sayHello = function () {
    console.log(`Hi, my name is ${this.name} and I'm ${this.age} years old.`);
  };
}

const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);

person1.sayHello(); // Hi, my name is Alice and I'm 30 years old.
person2.sayHello(); // Hi, my name is Bob and I'm 25 years old.

console.log(person1)
console.log(person2)

 

1) Person이라는 함수를 선언한다.

2) 함수 내부에서는 this에 접근하여 name, age 속성에 값을 대입한다.

3) new라는 키워드로 person1, person2 변수에 할당 (생성자 함수로 동작)

4) person1, person2를 콘솔로 출력하면 각각의 인스턴스 객체가 출력되고 this는 각각의 인스턴스 임을 알 수 있음.

 

 

그외 명시적 this 바인딩

call, apply, bind 메서드를 통해 별도의 대상을 바인딩하는 방법도 있다.

추후에 다시 알아보자

 

 

 

참고문서

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

 

this - JavaScript | MDN

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다. 또한 엄격 모드와 비엄격 모드에서도 일부 차이가 있습니다.

developer.mozilla.org

https://ko.javascript.info/object-methods

 

메서드와 this

 

ko.javascript.info

https://product.kyobobook.co.kr/detail/S000001766397

 

코어 자바스크립트 | 정재남 - 교보문고

코어 자바스크립트 | 자바스크립트의 근간을 이루는 핵심 이론들을 정확하게 이해하는 것을 목표로 합니다!최근 웹 개발 진영은 빠르게 발전하고 있으며, 그 중심에는 자바스크립트가 있다고

product.kyobobook.co.kr

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts