Javascript의 this

silverj-kim·2020년 10월 9일
0
post-custom-banner

자바스크립트로 개발하다보면 무조건 만나는 this
항상 헷갈리고 어설프게 알고 있는 것 같아 연휴 맞이 정리를 하려고 한다.

this

대부분의 this 의 경우 함수를 호출한 방법에 의해 결정되며
실행중에는 새로 할당할 수 없고 함수를 호출할 때마다 다를 수 있다.

ES5는 함수를 어떻게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드를 도입 ES6 부터는 this 바인딩을 제공하지 않는 화살표 함수를 추가했다.

Excution context 실행 컨텍스트

global execution context

전역 실행 컨텍스트에서 this는 전역 객체를 참조

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

a = "cafe";
this.b = "coffee";

console.log(window.a); //cafe
console.log(window.b); //coffee
console.log(b); //coffee

function execution context

단순 호출

엄격모드에서 this값은 실행 문맥에 진입하여 설정되는 값을 유지한다. 엄격모드가 아닐 때는 기본값으로 브라우저에서는 window 인 전역 객체를 참조한다.

function f1() {
  return this;
}

f1() === window; //true;

function f2() {
  "use strict"
  return this;
}

f2() === undefined; //true

this 의 값을 한 문맥에서 다른 문맥으로 넘기려면 call() 이나 apply() 를 사용해야 한다.
call 또는 apply의 첫 번째 인자로 객체가 전달될 수 있으며 this가 그 객체에 묶인다.

let obj = { a : "Custom" };
let a = "Global;

function whatsThis() {
  return this.a;
}

whatsThis(); //"Global;
whatsThis.call(obj); //"Custom"
whatsThis.apply(obj); // "Custom"

bind()

f.bind(someObj)를 호출하면 f와 같은 코드와 범위를 가졌지만 this는 원본 함수를 가진 새로운 함수가 생성된다. 새 함수의 this는 호출방식과 상관없이 영구적으로 bind()의 첫번째 매개변수로 고정된다. 그리고 bind는 한번만 동작한다!

function f() {
  return this.a;
}

let g = f.bind({a : "a"});
console.log(g()); //a

let h = g.bind({a : "aa"});
console.log(h()); //a

화살표 함수

화살표 함수에서 this는 자신을 감싼 정적 범위 lexical context 이다.
전역 코드에서는 전역 객체를 가리킨다.
화살표 함수를 call, bind, apply를 사용해 호출해 this의 값을 정해주더라도 무시한다.

let globalObj = this;
let foo = (() => this);
console.log(foo() === globalObj); //true;

객체의 프로토타입 체인에서의 this
mdn 문서를 보면서 흥미로웠던 부분

let o = {
  f: function() { return this.a + this.b }
}
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); //5

생성자로서
함수를 new 키워드와 함께 생성자로 사용하면 this는 새로 생긴 객체에 묶인다.

function C() {
  this.a = 37;
}

let o = new C();
console.log(o.a); //37

function C2() {
  this.a = 37;
  return {a : 38};
}

o = new C2();
console.log(o.a); //38

참고 : MDN This

profile
Front-end developer
post-custom-banner

0개의 댓글