ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • javascript의 this에 대해 꼭 알아야하는 핵심
    JavaScript 2023. 11. 26. 21:28

    "this는 함수를 호출한 객체이다"

     

    this는 객체를 가리키는 키워드이다.

    그런데 상황에 따라 뭘 가리키는지 달라지므로 살펴보자.

    1. Global scope에서 : window 객체 - 브라우저의 정보를 갖고 있음

     

    브라우저에서 위 코드를 실행하면 현재 브라우저의 여러 정보가 담긴 객체가 호출된다.

    나는 node.js로 실행시켰기에 빈 객체가 호출되었다.

     

    2. function scope에서 : 함수를 호출한 객체

    여기서는 먼저 브라우저로 실행시켰다.

    function main() {
      console.log(this);
    }
    
    console.log(window);
    
    main();

     

    JS로 함수를 만들면, window 객체의 내부에 함수가 저장된다.

    JS에서 만든 main함수가 window 객체에 포함되어 있다.

    따라서 위 코드처럼 main()을 호출하면,

    window객체가 main 함수를 호출한다.

     

    즉, 아래 두 코드가 같은 의미이다.

    main();
    window.main();

     

    함수 범위에서 this는 "함수를 호출한 객체"를 가리킨다고 했으니,

    이 경우 this가 가리키는 것은 window이다. 

     

    window 객체가 두 번 호출된 것을 확인할 수 있다.

     

    노드에서 실행한 결과도 광역 객체가 출력된다.

     

    그러나 엄격모드에서는 다르다.

    더보기

    Strict Mode

     

    'use strict';

    를 써주면 엄격 모드가 실행된다.

    이는 js 문서를 엄격한 문법에 따라 실행하며,

    변수를 선언하지 않고 실행하는 등

    기존 자바스크립트에서 잘 못 써도 허용됐던 오류들을 그냥 넘어가지 않고 오류를 발생시킨다.

    'use strict';
    
    function main() {
      console.log(this);
    }
    
    main();

    엄격모드에서는 위 코드를 실행 시, undefined가 뜬다.

     

    window.main()으로 코드를 작성해야 window 객체가 출력된다.

     

    3. 객체 메서드에서

    const object = {
      name : '김휴고',
      main : function() {
        console.log(this)
      }
    }
    
    object.main();

     

    이 this는 무엇을 가리킬까?

    object 객체가 출력된 것을 확인할 수 있다.

     

    이는 객체의 다른 속성에 접근할 때 유용하다.

    this를 통해 객체의 name 속성을 출력했다.

     

    const object = {
      name: "김휴고",
      main: function () {
        console.log(this);
      },
    };
    // object.main();
    
    const main2 = object.main;
    
    main2();

    위와 같이

    객체 내의 함수를 다른 변수에 저장해서 사용하면

    this는 뭘 가리키게 될까?

     

    다시 광역 객체, 브라우저에서는 window객체를 가리키게 된다.

    "함수를 호출한 객체"를 가리키는 this이므로

    위 상황에서 메서드는 더 이상 object에 의해 호출되는 것이 아니라

    main2를 통해 호출되기 때문이다.

     

    function main() {
      console.log(this);
    }
    
    const object = {
      name: "김휴고",
      main,
    };
    object.main();

     

    이번에는 함수를 객체 바깥에서 정의한 뒤,

    객체의 메서드로 포함시켰다.

    이 경우에도 

    object 객체가 출력된다.

     

    즉, this가 어디에서 정의되었는지는 중요하지 않다.

    this를 호출한 객체가 중요한 것이다.

     

    function main() {
      console.log(this);
    }
    
    const object = {
      name: "김휴고",
      smallObject: {
        name: "작은 김휴고",
        main,
      },
    };
    object.smallObject.main();

     

    이번에는 위와 같이 객체 안에

    또 다른 객체를 만들고

    거기에 main 메서드를 만들었다.

     

    이제 this는 뭘 가리키고 있을까?

     

    정답은 smallObject이다.

    main을 직접 호출한 객체는 smallObject이기 때문이다.

     

    4. Bind() : this가 가리키는 객체를 고정하고 싶을 때

    bind 함수는 괄호 안의 객체가 this 값으로 고정된 새로운 함수를 반환한다.

     

    function main() {
      console.log(this);
    }
    
    const mainBind = main.bind({ name: "묶였다네" });
    
    //광역 범위에서 mainBind을 호출할 때
    mainBind();
    
    //객체에  mainBind를 메서드로 추가한 뒤 호출할 때
    const object = {
      mainBind,
    };
    
    object.mainBind();

    이 경우 bind 되어 있지 않다면

    윈도우 객체와 오브젝트 객체가 호출될 것이다.

     

     

    그러나 bind로 지정한 객체를

    this가 항상 가리키고 있다.

     

    * bind를 두 번 하면? -> 두 번째 바인딩부터는 무시가 된다.

     

    5. 이벤트 처리기에서

    이벤트처리기에서 this가 어떻게 작동하는지 확인하기 위해

    다음과 같은 html과 js를 짰다.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <script defer src="./js/this6.js"></script>
        <title>Document</title>
      </head>
      <body>
        <button id="btn">버튼</button>
        
      </body>
    </html>
    const button = document.getElementById("btn");
    
    button.addEventListener("click", function () {
      console.log(this);
      console.log(this === this);
    });

     

    버튼을 클릭할 때마다 이벤트가 발사하고 함수가 수행된다.

    실행 결과는를 보면,

     

     

    this는 해당 이벤트를 발사한 요소를 가리킴을 확인할 수 있다.

     

     

    이 포스팅은 다음 영상을 참고했다.

    https://www.youtube.com/watch?v=j6VkGimAs-E&list=PLZ5oZ2KmQEYiGLIDlsTQR_wdfCH9ZD6lx&index=2

     

Designed by Tistory.