본문 바로가기
Frontend/JavaScript

JavaScript에서 this는 무엇을 가리키는걸까?

by 코딩쥐 2024. 7. 29.

JavaScript의 this는 인스턴스 자신을 가리키는 참조변수다. JavaScript의 this의 경우에는 다른 언어와 다르게 작동하는데, 어디에 위치하느냐에 따라서 가리키는 대상이 다르다. 위치에 따라 가리키는 대상을 작성해보았는데, JavaScript의 this의 경우에는 예측하기가 굉장히 어렵다. 

위치 대상
전역 객체 공간 window
함수 window
함수 내의 함수  window
객체 내의 함수 객체
객체1 내의 객체2 내의 함수 객체2
객체 내의 함수 내의 함수 window
DOM이벤트 내의 함수 이벤트의 대상
DOM이벤트 내의  arrow함수 window
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn1">버튼</button>
    <script>
        // 전역 객체 공간
        console.dir(this); // Window
        
        // 함수
        function func1(){
            console.dir(this); // window 
        }
        func1();

        // 함수 내의 함수
        function func2(){
            function func2_1(){
                console.dir(this); //window
            }
            func2_1();
        }
        func2();

        // 객체 내의 함수
        const obj1 = {
            a : function func3(){
                console.dir(this); //obj1
            }
        };
        obj1.a();

        // 객체1 내의 객체2 내의 함수
        const obj2 = {
            obj2_1 : {
                a : function func4(){
                    console.dir(this); //obj2_1
                }
            }
        }
        obj2.obj2_1.a();


        // 객체 내의 함수 내의 함수
        const obj3 = {
            a : function func5(){
                function func5_1(){
                    console.dir(this); //window
                }
                func5_1();
            }
        };
        obj3.a();

        // DOM이벤트 내의 함수
        document.querySelector("#btn1").addEventListener("click", function(){
            console.dir(this);  //button#btn1
        });

        //DOM이벤트 내의 arrow함수 
        document.querySelector("#btn1").addEventListener("click", ()=>{
            console.dir(this);  //window
        });
    </script>
</body>

</html>

 

call, apply, bind

위에서 봤다시피 this는 JavaScript 내부 규칙에 따라 결정되기 때문에 예측하기가 어렵다. 함수에서 window가 아닌 다른 객체를 this로 참조하고 싶을 때는 call / apply / bind 함수를 사용하면 된다. 

  • call(this, 인수1, 인수2, ...);
    this값 및 인수와 함께 함수를 호출한다. call()메서드의 경우 매개변수로 인수 목록을 받는다.
     
  • apply(this, [배열 | 유사배열객체]);
    this값 및 인수와 함께 함수를 호출한다. call()메서드와 다르게 apply()의 경우 매개변수로 인수 배열하나를 받는다. 

  • bind(this, 인수1, 인수2, ... );
    bind()메서드가 호출되면 함수와 this값을 유지하는 새로운 함수를 생성한다.
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // call();
        function func1(a,b,c){
            console.log(this, a, b, c);
        }
        let arr1 = [1,2,3,4];

        func1(5,6,7); // Window 5 6 7
        func1.call(arr1,5,6,7); // [1, 2, 3, 4] 5 6 7 

        // apply();
        function func2(a,b,c){
            console.log(this, a, b, c);
        }
        let obj1 = {
            a : 1,
            b: 2,
            c: 3
        }

        func2(5,2,1); // Window 5 2 1
        func2.apply(obj1, [5,2,1]); // {a: 1, b: 2, c: 3} 5 2 1

        // bind();
        function func3(a,b,c){
            console.log(this, a, b, c);
        }
        let arr2 = [4,5,6];
        let func3copy = func3.bind(arr2);
        func3copy(1,2,3); // [4, 5, 6] 1 2 3
    </script>
</body>

</html>