[자바스크립트 문법] this

김형빈·2024년 4월 30일
0

this

  • 실행 컨텍스트가 생성될 때 결정된다
  • 함수를 호출할 때 결정된다

전역 공간에서의 this

1. 전역 공간에서 this는 전역 객체를 가르킨다
  • window: 브라우저 환경
  • global: node 환경

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

  1. 함수 vs 메서드
    • 함수는 독립성을 가짐
    • 메서드는 .이나 []로 호출한다
  2. 메서드 내부에서의 this
    • 호출을 누가 했는지에 대한 정보가 담긴다
      var obj = {
      	methodA: function () { console.log(this) },
      	inner: {
      		methodB: function() { console.log(this) },
      	}
      };
      //
      obj.methodA();             // this === obj
      obj['methodA']();          // this === obj
      //
      obj.inner.methodB();       // this === obj.inner
      obj.inner['methodB']();    // this === obj.inner
      obj['inner'].methodB();    // this === obj.inner
      obj['inner']['methodB'](); // this === obj.inner

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

  • 어떤 함수를 함수로서 호출할 경우, this는 지정되지 않는다

  • 함수로서 독립적으로 호출할 때는 this는 항상 전역객체를 가리킨다

  • 매서드 내부 함수에서의 this 우회

    1. 변수를 활용하는 방법

      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();
  1. 화살표 함수(this를 바인딩하지 않는 함수)
       var obj = {
    			outer: function() {
    				console.log(this); // (1) obj
    				var innerFunc = () => {
    					console.log(this); // (2) obj
    				};
    				innerFunc();
    			}
    		}
    	
    		obj.outer();

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

  1. 콜백 함수도 함수기 때문에 this는 전역 객체를 참조
    • setTimeout 함수, forEach 메서드 콜백 함수를 호출할 때 대상이 될 this를 지정하지 않으므로, this는 전역 객체
  2. 콜백 함수에 별도로 this를 지정하는 경우
    • addEventListner 메서드는 콜백 함수 호출 시, 자신의 this를 상속하므로, this는 addEventListner의 앞부분(button 태그)

생성자 함수 내부에서의 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 바인딩

  1. call 메서드
var func = function (a, b, c) {
	console.log(this, a, b, c);
};

// no binding
func(1, 2, 3); // Window{ ... } 1 2 3

// 명시적 binding
// func 안에 this에는 {x: 1}이 binding돼요
func.call({ x: 1 }, 4, 5, 6}; // { x: 1 } 4 5 6
  1. apply 메서드
  • call과 똑같지만 나머지 부분을 배열 형태로 넘겨준다
var func = function (a, b, c) {
	console.log(this, a, b, c);
};
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6

var obj = {
	a: 1,
	method: function (x, y) {
		console.log(this.a, x, y);
	}
};

obj.method.apply({ a: 4 }, [5, 6]); // 4 5 6
  1. bind 메서드
  • 함수에 this를 미리 적용한다
  • 부분 적용 함수 구현할 때 용이하다
var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // window객체

// 함수에 this 미리 적용
var bindFunc1 = func.bind({ x: 1 }); // 바로 호출되지는 않아요! 그 외에는 같아요.
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8

// 부분 적용 함수 구현
var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4와 5를 미리 적용
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9
  • name 프로퍼티
    • bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 'bound'라는 접두어가 붙는다
var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
var bindFunc = func.bind({ x:1 }, 4, 5);

// func와 bindFunc의 name 프로퍼티의 차이를 살펴보세요!
console.log(func.name); // func
console.log(bindFunc.name); // bound func
  • 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
  1. 내부 함수
// 변수를 활용한 방법
var self = this;
	var innerFunc2 = function() {
		console.log(self); // (3) outer
	};
	innerFunc2();
//call을 활용한 방법
var obj = {
	outer: function() {
		console.log(this); // obj
		var innerFunc = function () {
			console.log(this);
		};

		// call을 이용해서 즉시실행하면서 this를 넘겨주었습니다
		innerFunc.call(this); // obj
	}
};
obj.outer();
  1. 콜백 함수
var obj = {
	logThis: function () {
		console.log(this);
	},
	logThisLater1: function () {
		// 0.5초를 기다렸다가 출력해요. 정상동작하지 않아요.
		// 콜백함수도 함수이기 때문에 this를 bind해주지 않아서 잃어버렸어요!(유실)
		setTimeout(this.logThis, 500);
	},
	logThisLater2: function () {
		// 1초를 기다렸다가 출력해요. 정상동작해요.
		// 콜백함수에 this를 bind 해주었기 때문이죠.
		setTimeout(this.logThis.bind(this), 1000);
	}
};

obj.logThisLater1();
obj.logThisLater2();
  • 화살표 함수가 더 좋은 방법?
    • 상황에 따라 변수 우회, call, apply, bind보다 편리한 방법이다
var obj = {
	outer: function () {
		console.log(this);
		var innerFunc = () => {
			console.log(this);
		};
		innerFunc();
	};
};
obj.outer();
profile
The secret of getting ahead is getting started.

0개의 댓글