• this

    2022. 9. 10.

    by. JJo 😊

    this? this! 🤔

    this는 메서드를 호출할 때, 일반 함수를 호출할 때도 만들어지며, 이벤트 리스너가 호출될 때에도 만들어진다. 이때, this는 동일한 값이 아니며 함수를 호출하는 방법에 의해 결정된다. 따라서, 다양한 경우에 this에 어떤 값이 들어가는지 판단할 수 있어야 한다.

    📌일반 함수에서의 this

    var data=10;
    
    function outer(){
        this.data=20; //window.data = 20
        data=30;
    
        document.write("1. data1 = "+data,"<br>");
        document.write("2. this.data = "+this.data,"<br>");
        document.write("3. window.data = "+window.data,"<br>");
    }
    
    outer();
    /*
     출력결과
         1. data = 30
         2. this.data = 30
         3. window.data = 30
     */

    일반 함수 내부에서 this는 전역 객체인 window가 저장된다. 따라서, this.data은 window.data와 동일하기 때문에 전역변수 data에 저장된다.

    📌일반 중첩 함수에서의 this

    var data=10;
    function outer(){
        // 중첩함수
        function inner(){
            this.data=20;
            data=30;
    
            document.write("1. data1 = "+data,"<br>");
            document.write("2. this.data = "+this.data,"<br>");
            document.write("3. window.data = "+window.data,"<br>");
        }
        inner();
    }
    outer();
    /*
     실행결과
     1. data = 30
     2. this.data = 30
     3. window.data = 30
     */

    일반 중첩 함수에서도 this는 window 객체를 가리킨다.

    📌메서드에서의 this

    var data=10;
    // 클래스 정의
    function MyClass() {
        // 프로퍼티 정의
        this.data=0;
    }
    
    // 메서드 정의
    MyClass.prototype.method1=function(){
        this.data=20;
        data=30;
    
        console.log("1. data1 = "+data);
        console.log("2. this.data = "+this.data);
        console.log("3. window.data = "+window.data);
    }
    
    // 인스턴스 생성
    var my1 = new MyClass();
    // 메서드 호출
    my1.method1();
    
    /*
     실행결과
     1. data = 30
     2. this.data = 20
     3. window.data = 30
     */

    메서드에서 this는 메서드를 호출한 객체가 저장된다. 위 코드에서 this.data는 MyClass 객체의 프로퍼티가 된다.

    📌메서드 내부의 중첩 함수에서의 this

    var data=10;
    // 클래스 정의
    function MyClass() {
        // 프로퍼티 정의
        this.data=0;
    }
    
    // 메서드 정의
    MyClass.prototype.method1=function(){
        function inner(){
            this.data=20;
            data=30;
    
            console.log("1. data1 = "+data);
            console.log("2. this.data = "+this.data);
            console.log("3. window.data = "+window.data);
        }
    
        inner();
    }
    
    // 인스턴스 생성
    var my1 = new MyClass();
    // 메서드 호출
    my1.method1();
    
    /*
     실행결과
     1. data = 30
     2. this.data = 30
     3. window.data = 30
     */

    객체의 메서드 내부에 만들어지는 중첩 함수에서의 this는 객체가 아닌 window가 된다.

    📌이벤트 리스너에서의 this

    var data=10;
    $(document).ready(function(){
    
        // 이벤트 리스너 등록
        $("#myButton").click(function(){
            this.data=20;
            data=30;
    
            console.log("1. data1 = "+data);
            console.log("2. this.data = "+this.data);
            console.log("3. window.data = "+window.data);
        });
    });
    /*
     실행결과
     1. data = 30
     2. this.data = 20
     3. window.data = 30
     */

    이벤트 리스너에서 this는 이벤트를 발생시킨 객체가 된다. 위 코드에서 this는 #myButton이 된다. 이에 따라 this.data=20는 #myButton 객체에 data라는 프로퍼티를 동적으로 추가하는 구문이 된다.

    📌이벤트 리스너 내부 함수에서의 this

    $('div').on('click', function() {
      console.log(this); // <div>
      function inner() {
        console.log('inner', this); // inner Window
      }
      inner();
    });

    이벤트 리스너의 this는 이벤트를 발생시킨 객체이므로 위 코드에서 두번째 라인의 this는 <div>를 가리킨다.

    근데 이벤트 내부의 inner( )함수 내의 this는 window를 가르킨다. 즉, 이벤트 리스너에서의 this와 이벤트 리스너 내부 함수의 this가 서로 동일한 객체를 가리키고 있지 않아 문제가 생길 수 있다.. 이러한 문제를 해결하기 위해서는 다음과 같이 코드를 수정하여 처리해야 한다.

    1️⃣ this를 that이라는 변수에 저장한다.

    $('div').on('click', function() {
      console.log(this); // <div>
      var that = this;
      function inner() {
        console.log('inner', that); // inner <div>
      }
      inner();
    });

    2️⃣ ES6 화살표 함수를 사용한다.

    화살표 함수는 자신이 선언된 함수 범위에서 this를 정의한다.

    $('div').on('click', function() {
      console.log(this); // <div>
      const inner = () => {
        console.log('inner', this); // inner <div>
      }
      inner();
    });

    참고 사이트

    https://poiemaweb.com/js-this#3-생성자-호출-패턴constructor-invocation-pattern

     

    this | PoiemaWeb

    자바스크립트의 this keyword는 Java와 같은 익숙한 언어의 개념과 달라 개발자에게 혼란을 준다. Java에서의 this는 인스턴스 자신(self)을 가리키는 참조변수이다. this가 객체 자신에 대한 참조 값을

    poiemaweb.com

     

    728x90

    'Javascript' 카테고리의 다른 글

    공공(오픈)데이터 API  (0) 2023.04.02
    reduce 활용하기  (0) 2022.11.17
    데이터 불변성  (0) 2022.09.10
    JS 프로처럼 쓰는 팁  (0) 2022.09.05
    데이터 불변성  (0) 2022.09.02

    댓글