상황에 따라지는 this

신은수·2023년 4월 21일
0

VanillaJS

목록 보기
5/11
  • this자신이 속한 객체 또는 자신이 생성할 인스턴스
  • 실행컨텍스트는 함수가 호출할 때 생성, this는 함수를 호출할 때 결정

1) 전역공간에서의 this

  • 전역공간에서 this전역 객체(window)

  • 전역 컨텍스트를 생성하는 주체가 전역 객체이기 때문

  • 전역변수를 선언 하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로도 할당

    var a = 1; 
    console.log(a); // 1
    console.log(window.a); // 1
    console.log(this.a); // 1
  • window의 프로퍼티에 직접 할당하더라도 결과적으로 var로 선언한 것과 똑같이 동작

    var a = 1;
    window.b = 2;
    console.log(a, window.a, this.a);
    console.log(b, window.b, this.b);

  • 삭제(delete) 명령은 전역변수 선언과 전역객체 프로퍼티 할당이 다르게 동작함

  • 처음부터 전역객체의 프로퍼티로 할당한 경우에는 삭제가 되는 반면, 전역변수로 선언한 경우에는 삭제가 되지 않음

  • 전역변수 선언시 전역 객체의 프로퍼티로 할당하며 해당프로퍼티의 configurable속성(변경 및 삭제 가능성)을 false로 정의하는 것

    var a = 1;
    delete window.a // false
    console.log(a, window.a, this.a) // 1 1 1
    
    window.b = 2;
    delete window.b; // true
    console.log(b, window.b, this.b) // Uncaught ReferenceError: b is not defined

2) 메서드로서 호출할 때 그 메서드 내부에서의 this

a) 함수로서의 호출, 메서드로서의 호출 비교

  • 함수 앞에 점(.)이 없으면 함수로서 호출,
    함수(메서드) 앞에 점이 있으면 메서드로서 호출

    var func = function (x) {
        console.log(this, x);
    };
    func(1); // Window{...} 1
    
    var obj = {
      method: func
    };
    obj.method(2); // {method: ƒ} 

b) 메서드 내부에서의 this

  • this는 호출한 주체에 대한 정보가 담김.

  • 즉, 바로 함수명 앞의 객체this

    var obj1 = {
        outer: function () {
            console.log(this);
            var innerFunc = function () {
                console.log(this);
            }
            innerFunc(); // 2 함수로서 호출
    
            var obj2 = {
                innerMethod: innerFunc
            };
            obj2.innerMethod(); // 3 메서드로서 호출
        }
    };
    obj1.outer(); // 1 메서드로서 호출
  • 어떤 함수를 메서드로서 호출하는 경우 호출 주체는 함수명 앞의 객체


3) 함수로서 호출 할 때 그 함수 내부에서의 this

a) 함수 내부에서의 this

  • 함수로서 호출할 경우 this가 지정되지 않음. this에는 호출 주체가 담기는데 함수로 호출할 때는 호출주체(객체)를 명시하지 않기 때문. this가 지정되지 않은 경우 this는 전역객체를 가리킴

b) 메서드 내부함수에서의 this

function global(){
 	console.log(this);
}
var obj1 = {
    outer: function () {
        console.log(this); 
        var innerFunc = function () {
            console.log(this); 
        }
        innerFunc(); // 2 (메서드 내부) 함수로서 호출

        var obj2 = {
            innerMethod: innerFunc
        };
        obj2.innerMethod(); // 4 메서드로서 호출
    }
};
global(); // 1. 함수 내부에서의 호출
obj1.outer(); // 2. 메서드로서 호출

// window, outer, window, obj2

this 바인딩에 관해서는 함수를 실행하는 당시의 주변환경(메서드 내부인지, 함수 내부인지 등)은 중요하지않고, 오직 해당 함수를 호출하는 구문 앞에 점 또는 대괄호 표기가 있는지 없는지가 관건

c) 메서드 내부함수에서의 this를 우회하는 방법

  • 변수 활용
  • this를 바인딩하지 않도록 화살표함수를 쓰기
    var obj = {
    	outer: function(){
    			console.log(this); // {outer: f}
        		var innerFunc = ()=>{
               	 console.log(this); // {outer: f}
              }
              innerFunc();
      	}
    }
    obj.outer();

4) 콜백함수 호출 시 그 함수 내부에서의 this

  • 콜백 함수의 제어권을 가지는 함수(메서드)가 콜백함수에서 this를 무엇으로 할 지를 결정, 특별히 지정하지 않은 경우에는 기본적으로 함수와 마찬가지로 전역객체를 바라봄

  • setTimeout(function(){console.log(this);}, 300); // window
    [10,20,30].forEach(function(){console.log(this);}) // window window window 
    
     document.body.innerHTML += '<button id="a">클릭</button>'
     document.body.querySelector("#a")
       .addEventListener('click', function(e){console.log(this)})

5) 생성자 함수 내부에서의 this

  • 어떤 함수가 생성자로서 호출된 경우 내부에서의 this는 곧 새로 만들 구체적인 인스턴스 자신이 됨
profile
🙌꿈꾸는 프론트엔드 개발자 신은수입니당🙌

0개의 댓글