this

wonway·2024년 3월 4일
post-thumbnail

요약

this는 현재 실행 컨텍스트의 객체를 가리키는 식별자이다.

this의 값은 함수 호출 방식에 따라 변경된다.

5가지 방식

  • 글로벌 컨텍스트 : 전역 실행 컨텍스트에서는 window 전역 객체를 가리킴
  • 함수 컨텍스트 : 일반 함수에서는 window 전역 객체를 가리킴, use strict를 쓰면 undefined, 메서드에서 호출하면 메서드를 호출한 객체를 가리킴
  • 생성자 함수 컨텍스트 : 생성된 인스턴스 객체를 가리킴
  • 명시적 바인딩 : call(), apply(), bind() 메서드를 사용해서 this의 값을 명시적으로 설정할 수 있음
  • 화살표 함수 : 상위 스코프의 this를 상속 받아서 가리킴

객체의 다른 속성이나 메서드에 접근하는 방법을 위해 주로 사용한다.

const person = {
  name: '홍길동',
  age: 25,
  greet: function() {
    console.log('안녕하세요, ' + this.name + '입니다.'); //객체 내의 name 속성에 접근
  },
  updateAge: function(year) {
    this.age += year;
    this.greet(); // 객체 내의 다른 메서드 호출
  }
};

const person = {
  name: '홍길동',
  age: 25,
  greet: function() {
    console.log('안녕하세요, ' + person.name + '입니다.'); // 'this' 대신 객체 이름 'person' 사용
  },
  updateAge: function(year) {
    person.age += year;
    person.greet(); // 'this' 대신 객체 이름 'person' 사용
  }
};

물론 직접 객체의 이름을 참조하여 접근할 수도 있지만 객체를 복사하거나 변경할 때 참조한 이름을 전부 수정해야하는 비효율이 발생한다. this를 사용하면 재사용성 향상과 유지보수가 편리해진다.

this의 정의

실행 컨텍스트의 객체를 가리키는 키워드.
따라서 함수를 호출한 방법에 의해 결정된다.

this의 값이 결정되는 방식

실행 컨텍스트에서 this

  • this의 값은 함수가 호출되는 방식에 따라 결정되며 this는 실행 컨텍스트의 일부이다.

글로벌 컨텍스트에서 this

  • 전역 실행 컨텍스트에서는 글로벌 객체를 가리킨다.
    • 웹브라우저에서는 window 객체가 된다.
    • Node.js에서는 global 객체가 된다.

함수 호출에서 this

  • 일반적인 함수 호출에서는 전역 객체를 가리킨다.
    • use strict 엄격모드에서는 undefined가 된다.

메소드 호출에서 this

  • 메소드를 호출한 객체를 가리킨다.
    //객체의 메소드 내에서 this를 사용하여 해당 객체의 다른 속성이나 메소드에 접근
    const person = {
      name: 'John',
      greet: function() {
        console.log(`Hello, my name is ${this.name}`);
      }
    };
    
    person.greet(); // 출력: "Hello, my name is John"
    

생성자 함수에서의 this

  • 생성되는 인스턴스를 가리킨다.
    //생성자 함수에서 this를 사용하여 새 객체 인스턴스에 속성을 추가
    function Person(name) {
      this.name = name;
      this.greet = function() {
        console.log(`Hello, my name is ${this.name}`);
      };
    }
    
    const alice = new Person('Alice');
    alice.greet(); // 출력: "Hello, my name is Alice"
    

화살표 함수에서의 this

  • 주변의 실행 컨텍스트의 this를 상속 받는다.
  • 자신에게 속한 this가 없다.
    function Person() {
      this.name = 'John';
      setTimeout(() => {
        console.log(`Hello, my name is ${this.name}`); // 화살표 함수 안의 `this`는 Person 인스턴스를 가리킴
      }, 1000);
    }
    
    const person = new Person();
    

bind 메소드를 통한 명시적 바인딩

  • this가 가리키는 대상을 직접 설정할 수 있는 메소드
    const person = {
      name: 'John',
      greet: function() {
        console.log(`Hello, my name is ${this.name}`);
      }
    };
    
    const greet = person.greet.bind({ name: 'Alice' });
    greet(); // 출력: "Hello, my name is Alice"
    

이벤트 핸들러에서 this

  1. 이벤트 핸들러에서 this는 이벤트를 받는 DOM 요소를 가리킨다.
    <button id="myButton">Click me</button>
    
    <script>
      document.getElementById('myButton').addEventListener('click', function() {
        console.log(this); // `this`는 버튼 요소를 가리킴
      });
    </script>
    
  1. 화살표 함수를 사용하면 상위 스코프의 this를 상속 받는다. (기존의 화살표 함수 메커니즘)

  2. 명시적 this 바인딩

  • 예시 : 이벤트 핸들러에 객체의 메서드를 등록할 때
    <button id="myButton">Click me</button>
    
    const button = document.getElementById('myButton');
    
    const obj = {
      buttonText: 'Button has been clicked!',
      clickHandler: function() {
        console.log(this.buttonText);
      }
    };
    
    // `clickHandler` 메서드가 `obj` 객체에 바인딩되도록 명시적으로 `this`를 설정
    button.addEventListener('click', obj.clickHandler.bind(obj));
    

예제는 버튼에 이벤트를 등록하는 경우이다.

그런데 이벤트는 obj의 메서드이다.

이런 경우 obj.clickHandler()를 참조해야하는데 this가 어디를 가리키는지가 의도한 동작이 이뤄지는 중요한 요인이 된다.

이 때 .bind() 메서드를 사용하면 this를 명시적으로 지정할 수 있다.

bind()를 사용하지 않으면 기본적으로 DOM 요소를 가리키게 된다.

this가 중요한 이유

객체지향 프로그래밍

  • this를 사용하면 객체의 메서드 내에서 현재 객체의 속성이나 다른 메서드에 접근할 수 있다.
  • 위의 버튼 이벤트 예제를 생각해보면 obj의 다른 속성과 메서드가 있을 경우 obj에 bind하면 다른 속성과 메서드도 사용할 수 있는 것이다.

동적 컨텍스트의 이해

  • this의 값이 호출되는 방식에 따라 변경되므로 this를 이해하고 제어할 수 있어야 한다.

this와 prototype

생성자 함수로 객체에 속성과 메서드를 정의하는 기능이라는 공통점이 보여서 비교를 해봤다.

기준thisprototype
정의실행 컨텍스트에 따라 현재 객체를 가리키는 참조이다.함수에 기본으로 포함된 속성으로, 객체 인스턴스들이 공유할 속성과 메서드를 가진다.
용도객체의 현재 인스턴스에 접근하고, 인스턴스별 고유 속성을 조작하기 위해 사용된다.모든 인스턴스가 공유할 수 있는 메서드와 속성을 정의하기 위해 사용된다.
작동 방식함수 호출 방식(일반 함수, 메서드 호출, 생성자 함수 등)에 따라 동적으로 결정된다.함수 객체가 생성될 때 함께 생성되며, 생성된 모든 인스턴스가 접근할 수 있는 프로퍼티와 메서드를 제공한다.
접근성메서드 내부에서 사용될 때 해당 메서드를 호출한 객체 인스턴스를 가리킨다.생성자 함수 또는 클래스를 통해 생성된 모든 객체 인스턴스에서 prototype에 정의된 속성과 메서드에 접근할 수 있다.
메모리각 인스턴스는 this를 통해 정의된 고유의 속성을 가지므로 메모리를 더 사용할 수 있다.prototype에 정의된 메서드는 모든 인스턴스가 공유하기 때문에 메모리 사용을 줄일 수 있다.
    **const obj = { 
    	name: 'John', 
    	greet: function() { 
    	console.log("Hello, " + this.name); 
    	} 
    }
    
    function Person(name) {
    	this.name = name;
    }; 
    Person.prototype.greet = function() { 
    	console.log("Hello, " + this.name); 
    };**

공통점

  • 둘 다 자바스크립트에서 객체 지향 프로그래밍을 가능하게 하는 중요한 개념이다.
  • 객체의 메서드 내에서 thisprototype을 통해 정의된 메서드 모두 this 키워드를 사용하여 현재 객체 인스턴스에 접근할 수 있다.

차이점

  • this는 객체의 현재 인스턴스를 가리키는 반면, prototype은 생성자 함수에 연결된 객체로, 모든 인스턴스가 공유하는 속성과 메서드를 보유한다.
  • this는 인스턴스별 고유 상태를 관리하는 데 사용되고, prototype은 메모리 효율성을 위해 모든 인스턴스가 공유할 메서드와 속성을 정의하는 데 사용됩니다.

this : 고유, prototype : 공유

profile
문제를 컴퓨터로 해결하는 데서 즐거움을 찾는 프론트엔드 개발자

0개의 댓글