Javascript

this [Javascript]

muyeon 2024. 1. 5. 22:38

this 란?

  • this 란 Javascript 예약어 이다.
  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.
  • this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다.

this 바인딩이란?

  • 식별자와 값을 연결하는 과정을 말한다.
  • 변수선언은 변수 이름과 확보된 메모리 공간의 주소를 바인딩하는 것이다.
  • this 바인딩은 this(키워드로 분류되지만 식별자의 역할을 한다.)와 this가 가리킬 객체를 바인딩하는 것이다.

다른 대부분의 객체 지향 언어에서 this 는 클래스로 생성한 인스턴스 객체를 의미한다.

클래스에서만 사용할 수 있기 때문에 혼란의 여지가 없거나 많지 않다.

하지만 자바스크립트는 어디서든 사용할 수 있다. 

상황에 따라 this 가 바라보는 대상이 달라진다.

 

함수와 객체(메서드)의 구분이 느슨한 자바스크립트에서는 this 는 실질적으로 이 둘을 구분하는 유일한 기능이다.

 


왜 상황에 따라 달라질까?

 

자바스크립트에서 this 는 실행 컨텍스트가 생성될때 함께 결정된다.

즉 this는 함수를 호출할 때 결정된다.

이는 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라진다는 것을 의미한다.

 


전역 this

 

전역공간에서 this 는 전역 객체를 가리킨다.

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

브라우저에서 전역객체는 window, Node.js 환경에서는 global 이다.

 

console.log(this === window) // true

 


메서드 내부에서의 this

 

어떤 함수를 실행할때 일반적인 방법 두 가지는 함수로 호출하거나 메서드로서 호출하는 경우이다.

이 둘은 미리 정의한 동작을 수행하는 코드 뭉치인데, 이 둘을 구분하는 차이는 독립성이다.

함수는 그 자체로 독립적인 기능을 수행하지만, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다.

 

메서드 내부 this

 

this 에는 호출한 주체에 대한 정보가 담긴다.어떤 함수를 메서드로서 호출하는 경우 호출 주체는 바로 함수명(프로퍼티명) 앞의 객체이다. dot 표기법의 경우 마지막 점 앞에 명시된 객체가 곧 this가 된다.

var obj = {
	methodA: function() { console.log(this) };
    inner: {
    	methodB: function() { console.log(this) };
    }
};

obj.methodA(); // { methodA: f, inner: {} }

obj.inner.methodB() // { methodB: f }

 

함수 this

 

this 에는 호출한 주체에 대한 정보가 담긴다. 

그런데 함수로서 호출하는 것은 호출 주체를 명시하지 않고 개발자가 코드에 직접관여해 실행한 것이기 때문에 호출 주체에 대한 정보를 알 수 없다.

함수로서 호출할 경우는 this 가 지정되지 않는다.

즉 this 가 지정되지 않은 경우는 전역 객체를 가리킨다.

 

메서드 내부함수에서의 this

 

var obj = {
	outer: function() {
    	console.log(this) // (1) obj1
        var innerFunc = function () {
        	console.log(this) // (2) window (3)obj2
        }
        innerFunc();
        
        var obj2 = {
    		innerMethod: innerFunc
    	};
        obj2.innerMethod();
    }
};
obj1.outer();
1. 객체 생성, 객체 내부에 outer 프로퍼티가 있고, 여기에 익명함수가 연결된다. 이 객체를 변수 obj 에 할당한다.
2. obj1.outer 를 호출한다.
3. obj1.outer 함수의 실행 컨텍스트가 생성되면서 호이스팅하고, 스코프 체인 정보를 수집해 this 바인딩한다.
   이 함수는 호출할 때 함수명인 outer 앞에 dot 이 있었으므로 메서드로서 호출한 것.
   따라서 마지막 점 앞의 객체인 obj1 이 바인딩 된다.
4. obj1 객체의 정보가 출력
5. 호이스팅된 변수 innerFunc 는 outer 스코프 내에서만 접근할 수 있는 지역변수이다.
   이 지역변수에 익명 함수를 할당한다.
6. innerFunc 를 호출한다.
7. innerFunc 함수의 실행 컨텍스트가 생성되면서 호이스팅, 스코프 체인 수집, this 바인딩 등을 수행한다.
   이 함수를 호출 할 때 함수명 앞에는 dot 이 없었다. 즉 함수로서 호출된 것이므로 this가 지정되지 않았고
   따라서 자동으로 스코프 체인상의 최상위 객체인 전역객체가 바인딩 된다.
8. window 객체 정보가 출력된다.
9. 호이스팅된 변수 obj2 또한 outer 스코프 내에서만 접근할 수 있는 지역변수이다.
   여기서 다시 객체를 할당하는데 그 객체에는 innerMethod 라는 프로퍼티가 있으며
   앞서 정의된 변수 innerFunc 와 연결된 익명 함수가 연결된다.
10. obj2.innerMethod 를 호출한다.
11. obj2.innerMethod 함수의 실행 컨텍스트가 생성된다. 이 함수는 호출할 때 함수명인 innerMethod 앞에
	dot 이 있었으므로 메서드로서 호출한 것이다. 따라서 this에는 마지막 점 앞의 객체인 obj2 가 바인딩된다.
12. obj2 객체 정보가 출력된다.

 

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

 


this 우회

 

var obj = {
	outer: function() {
    	console.log(this) // outer
        var innerFunc1 = function() {
            console.log(this) // window
        };
        innerFunc1();
        
        var self = this;
        var innerFunc2 = function() {
        	console.log(self); // outer
        };
        innerFunc2();
    }
}
obj.outer();

 

변수에 this 를 저장한 상태에서 호출한 innerFunc2 의 경우는 self 에는 객체가 obj 가 출력된다.

이는 상위 스코프의 this 를 저장해서 내부 함수에서 활용하려는 수단이다.

 


this 를 바인딩하지 않는 함수

 

ES6에서는 함수 내부에서 this 가 전역객체를 바라보는 문제를 보완하고자, this 를 바인딩하지 않는 화살표 함수가 등장했다.

 

var obj = {
	outer: function() {
    	console.log(this) // outer
        var innerFunc = () => {
        	console.log(this) // outer
        }
        innerFunc()
    }
}
obj.outer()

 

이 외에도 call, apply 등의 메서드를 활용해 함수를 호출 할 때 명시적으로 this 를 지정하는 방법이 있다.

 


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

 

함수 A의 제어권을 다른 함수(또는 메서드) B에게 넘겨주는 경우 함수 A 를 콜백함수라고 한다.

이때 함수 A 는 함수 B의 내부 로직에 따라 실행되고, this 역시 함수 B 내부로직에서 정한 규칙에 따라 값이 결정된다.

 

콜백함수도 함수이기 때문에 기본적으로 this 가 전역객체를 참조하지만, 제어권을 받은 함수에서 콜백 함수에 별도로 this 가 될 대상을 지정한 경우에는 그 대상을 참조하게 된다.

 

document.body.innerHTML = '<button id="a">클릭</button>";
document.body.querySelector('#a').addEventListener('click', function(e) {
	console.log(this, e);
});

 

addEventListener 메서드는 콜백 함수를 호출 할 때 자신의 this 를 상속하도록 정의되어 있다. 메서드명의 dot 앞부분이 곧 this 가 된다.

 

콜백 함수의 제어권을 가지는 함수(메스드)가 콜백 함수에서의 this 를 무엇으로 할지를 결정하며 특별히 정의하지 않은 경우는 전역객체를 바라본다.

 


생성자 함수 내부에서의 this

 

생성자 함수는 어떤 공통된 성질을 지니는 객체들을 생성하는데 사용하는 함수이다.

객체지향 언어에서는 생성자를 클래스, 클래스를 통해 만든 객체를 인스턴스라고 한다.

 

생성자는 구체적인 인스턴스를 만들기위한 틀이라고 보면 된다.

 

JS 에서는 new 명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작하게 된다.

그리고 어떤 함수가 생성자 함수로서 호출된 경우 내부에서의 this는 곧 새로 만들 구체적인 인스턴스 자신이 된다.

 

생성자 함수를 호출하면 우선 생성자의 prototype 프로퍼티를 참조하는 __proto__ 라는 프로퍼티가 있는 객체를 만들고, 미리 준비된 공통 속성 및 개성을 해당 객체(this) 에 부여한다. 이렇게 구체적인 인스턴스가 만들어진다.

 

var Cat = function(name, age) {
	this.bark = 'miao';
    this.name = name;
    this.age = age;
}

var choch = new Cat('choco', 7);
var nabi = new Cat('nabi', 5);

console.log(choco, nabi);

// Cat { bark: miao, name: choco, age: 7 }
// Cat { bark: miao, name: nabi, age: 5 }

 

Cat 변수에 익명 함수를 할당한다.

이 함수 내부에서 this 에 접근해 bark, name, age 프로퍼티에 각각 값을 대입한다.

실행한 생성자 함수 내부에서의 this는 choco 인스턴스와 , this는 nabi 의 인스턴스를 가리킴을 알 수 있다.

 


 

참고링크

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

 

this - JavaScript | MDN

A function's this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.

developer.mozilla.org

https://poiemaweb.com/js-this

 

this | PoiemaWeb

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

poiemaweb.com

https://im-developer.tistory.com/96

 

[JS/this] 자바스크립트, this의 4가지 역할

Javascript, This. 자바스크립트에는 this라는 키워드가 있다. this는 문맥에 따라서 다양한 값을 가지는 데, this가 쓰이는 함수를 어떤 방식으로 실행하느냐에 따라서 그 역할이 구별된다. this의 값들

im-developer.tistory.com

https://product.kyobobook.co.kr/detail/S000001766397

 

코어 자바스크립트 | 정재남 - 교보문고

코어 자바스크립트 | 자바스크립트의 근간을 이루는 핵심 이론들을 정확하게 이해하는 것을 목표로 합니다!최근 웹 개발 진영은 빠르게 발전하고 있으며, 그 중심에는 자바스크립트가 있다고

product.kyobobook.co.kr

https://hanamon.kr/javascript-this%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C/

 

[JavaScript] this 란 무엇일까? - 하나몬

자바스크립트의 this의 정의부터 용법까지 ⚡️ this의 정의 ❗️this란? this란 ‘이것’ 이란 뜻이다. this란 JavaScript 예약어다. ❗️this는? this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를

hanamon.kr