[TIL] this

·2023년 10월 17일
0

TIL

목록 보기
6/85
post-thumbnail

this

  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다.
  • this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메소드를 참조할 수 있다.
  • 자바스크립트의 this는 함수가 호출되는 방식에 따라 this에 바인딩될 값, 즉 this 바인딩이 동적으로 결정된다.

전역 공간에서의 this

  • 전역 공간에서 this는 전역 객체를 가리킨다.
  • 런타임 환경에 따라 가리키는 전역 객체가 다르다.
    • 브라우저 환경 : window
    • node 환경 : global

일반 함수 내부에서의 this

  • 일반 함수 내부에서 this는 전역 객체를 가리킨다.
  • 함수와 메서드의 차이는 독립성 이다.
  • 함수는 그 자체로 독립적인 기능을 수행한다.
  • 함수명();

메서드 내부에서의 this

  • 메서드는 자신을 호출한 대상 객체에 대한 동작을 수행한다.
  • 객체.메서드명()
  • 함수로서의 호출과 메서드로서의 호출 구분 기준은 . 또는 []이다.
  • obj.methodA(); => // this === obj
  • obj['methodA'](); => // this === obj
  • 메서드의 내부함수에서의 this라고 해도, 함수로서 호출한다면 this는 전역객체를 의미한다.
var obj1 = {
	outer: function() {
		console.log(this); // (1)
		var innerFunc = function() {
			console.log(this); // (2), (3)
		}
		innerFunc();

		var obj2 = {
			innerMethod: innerFunc
		};
		obj2.innerMethod();
	}
};
obj1.outer();

(1) : obj1, (2) : 전역객체, (3) : obj2

  • 그런데, 개발자 입장에서 이게 쉽게 받아들여지지 않는다. 그러므로 우회할 수 있는 방법이 있다.

  • 메서드 내부 함수에서의 this를 우회하는 방법
    1. 변수를 활용하는 방법

    • 내부 스코프에 이미 존재하는 this를 별도의 변수(ex. self)에 할당
    var obj1 = {
      outer: function() {
        console.log(this); // (1) outer
    
        // AS-IS
        var innerFunc1 = function() {
          console.log(this); // (2) 전역객체
        }
        innerFunc1();
    
        // TO-BE
        var self = this;
        var innerFunc2 = function() {
          console.log(self); // (3) outer
        };
        innerFunc2();
      }
    };
    // 메서드 호출 부분
    obj1.outer();

    2. 화살표 함수를 활용하는 방법

    • ES6에서 처음 도입된 화살표 함수는, 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다.
    • 따라서 this는 이전의 값(상위 값)이 유지된다.
    • ES6에서는 함수 내부에서 this가 전역 객체를 바라보는 문제 때문에 화살표 함수를 도입했다.
    var obj = {
        outer: function() {
            console.log(this); // (1) obj
            var innerFunc = () => {
                console.log(this); // (2) obj
            };
            innerFunc();
        }
    }
    
    obj.outer();

콜백 함수 내부에서의 this

  • 콜백 함수 : "어떠한 함수, 메서드의 매개변수로 넘겨주는 함수"
  • 콜백 함수도 함수이기 때문에 this는 전역 객체를 참조하지만, 콜백함수를 넘겨받은 함수(ex. addEventListener)에서 콜백 함수에 별도로 this를 지정한 경우에는 예외적으로 그 대상을 참조하게 되어있다.
// 별도 지정 없음 : 전역객체
setTimeout(function () { console.log(this) }, 300);

// 별도 지정 없음 : 전역객체
[1, 2, 3, 4, 5].forEach(function(x) {
	console.log(this, x);
});

// addListener 안에서의 this는 항상 호출한 주체의 element를 return하도록 설계되었음
// 따라서 this는 button을 의미함
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
	console.log(this, e);
});
  • setTiemout 함수, forEach 메서드는 콜백 함수를 호출할 때 대상이 될 this를 지정하지 않으므로, this는 곧 window객체
  • addEventListener 메서드는 콜백 함수 호출 시, 자신의 this를 상슥하므로, this는 addEventListner의 앞부분(button 태그)

생성자 함수 내부에서의 this

  • 생성자 : 구체적인 인스턴스(객체)를 생성하는 함수
  • 일반 함수와 동일한 방법으로 생성자 함수를 정의하고 new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
  • 생성자 함수 내부의 this는 생성자 함수가 (미래에) 생성할 인스턴스가 바인딩 된다.
var Cat = function (name, age) {
	this.bark = '야옹';
	this.name = name;
	this.age = age;
};

var choco = new Cat('초코', 7); // this : choco
var nabi = new Cat('나비', 5);  // this : nabi

✅ 정리

// 전역에서 this는 전역 객체 window를 가리킨다.
console.log(this); // window

function square(number) {
    // 일반 함수 내부에서 this는 전역 객체 window를 가리킨다.
    console.log(this); // window
    return number * number;
}
square(2);

const person = {
    name : 'Lee',
    getName() {
        // 메서드 내부에서 this는 메서드를 호출한 객체를 가리킨다.
        console.log(this);  // {name : 'Lee', getName : f} => person
        return this.name;
    }
};
console.log(person.getName()); // Lee

function Person(name) {
    this.name = name;
    // 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
    console.log(this); // Person {name: "Lee"}
}

const me = new Person('Lee');

⭐️ 표

함수 호출 방식this 바인딩
일반 함수 호출전역 객체
메서드 호출메서드를 호출한 객체
생성자 함수 호출생성자 함수가 (미래에) 생성할 인스턴스
Function.prototype.apply/call/bind 메서드에 의한 간접 호출Function.prototype.apply/call/bind 메서드에 첫번째 인수로 전달한 객체
profile
느리더라도 조금씩, 꾸준히

0개의 댓글