본문 바로가기
Developer/Javascript 해부학

[Javascript] this 란?

by 해적거북 2022. 1. 20.
728x90

github.com/JaeYeopHan/Interview_Question_for_Beginner

poiemaweb - 함수 호출 방식에 의해 결정되는 this


 

1. 서론

Javascript 에서는 함수가 실행될 때, 매개변수로 전달되는 인자값을 제외하고 arguments 객체와 this를 암묵적으로 받는다.

그리고 this는 함수를 실행할 때, 함수를 소유하고 있는 객체를 참조한다.

따라서 해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다.

(Java에서 this는 인스턴스 자신을 가리키는 참조변수)

(메서드 : 객체의 속성이 함수인 것)

 

 

2. 함수를 호출할 때

  • 특정 객체의 메서드가 아닌 함수 호출이면 해당 함수 내부 코드에서 사용된 this는 전역객체(browser : window / server : global)에 바인딩된다.
let test = function() {
    console.log(this); // Window { ... }
    function print() {
        console.log(this); // Window { ... }
    }
    print();
}

test();
// Window { ... }
// Window { ... }

 

 

3. 객체의 메서드를 호출할 때

  • 메서드를 호출한 객체로 바인딩
let test = {
    name : 'javascript',
    print : function() {
        console.log(this); // {name: 'javascript', print: f}
        function print2() {
            console.log(this); // Window{ ... }
        };
        print2();
    }
}

test.print();
// {name: 'javascript', print: f}
// Window{ ... }

 

 

4. 생성자 함수(new)를 통해 객체를 생성할 때

  • new 키워드를 통해서 호출된 함수 내부에서의 this는 객체 자신이 된다.
  • new 연산자를 통해 함수를 생성자로 호출하게 되면, 빈 객체가 생성되고 this가 바인딩 된다.
  • return 문이 없는 경우, this로 바인딩된 새로 생성한 객체가 반환된다.
function makeObject(name) {
  this.name = name;
  console.log(this);
  function print() {
    console.log(this);
  }
  print();
}

let test = new makeObject('javascript');
// makeObject {name : 'javascript'}
// Window { ... }

let test2 = makeObject('javascript');
// Window { ... }
// Window { ... }

 

 

5. apply, call, bind를 이용

  • 함수에 apply, call, bind를 이용하여 this로 바인딩 될 객체를 지정할 수 있다.
  • this와 parameter 지정
    • bind : 함수 선언시
    • call, apply : 함수 호출시
  • 파라미터 형식
    • apply : 첫번째 인자(this), 두번째 인자(배열)
    • bind, call : 첫번째 인자(this), 두번째 부터 각 파라미터 전달
// bind 메소드 예시
let test = {
    name: 'javascript',
    print: function() {
        console.log(this); // {name: 'javascript', print: f}
        let print2 = function(param1, param2) {
            console.log(this); // {name: 'javascript', print: f}
            console.log(param1, param2);
        }.bind(this, 'java', 'script');
        print2();
    }
};

test.print();
// {name: 'javascript', print: f}
// {name: 'javascript', print: f}
// java script
// call 메소드 예시
let test = {
    name: 'javascript',
    print: function() {
        console.log(this);
        let print2 = function(param1, param2) {
            console.log(this);
            console.log(param1, param2);
        };
        print2.call(this, 'java', 'script');
    }
};

test.print();
// {name: 'javascript', print: f}
// {name: 'javascript', print: f}
// java script
// apply 메소드 예시
let test = {
    name: 'javascript',
    print: function() {
        console.log(this);
        let print2 = function(param1, param2) {
            console.log(this);
            console.log(param1, param2);
        };
        print2.apply(this, ['java', 'script']);
    }
};

test.print();
// {name: 'javascript', print: f}
// {name: 'javascript', print: f}
// java script

 

 

6. Arrow Function (화살표 함수) + new (생성자 함수)

보통 일반 함수의 this는 전역객체를 가리키지만, 화살표 함수에서 this는 전달되는 객체를 가리키게 된다.

// 일반 함수 예시
function print() {
  this.name = 'javascript';
  console.log(this);
  function print2() {
    console.log(this);
  }
  print2();
}

print();
// Window { ... }
// Window { ... }

let test = print();
// Window { ... }
// Window { ... }

let test = new print();
// print {name: 'javascript'}
// Window { ... } ← 차이점
// 화살표 함수 예시
function print() {
  this.name = 'javascript';
  console.log(this);
  (() => {
    console.log(this);
  })();
}

print();
// Window { ... }
// Window { ... }

let test = print();
// Window { ... }
// Window { ... }

let test = new print();
// print {name: 'javascript'}
// print {name: 'javascript'} ← 차이점

 

 

7. 결론

보통 this는 전역객체를 바인딩하는데,

  • 객체의 메소드를 호출하거나,
  • 생성자 함수로 객체를 생성하거나,
  • apply, call, bind 함수를 사용하거나
  • Arrow Function을 통해

this가 해당 객체를 바인딩하도록 만들 수 있다.

 

 


 

728x90

댓글