All ContentsCategoryAbout

What is this?

05 June, 2020 - JavaScript - 3 min read

javascript

this는 호출하는 방식에 따라 달라지며, 크게 다섯 가지 경우로 나눌 수 있다.

1. 전역에서 this는 언제나 window

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

2. 일반 함수 호출은 언제나 window

function normalFunc1() {
  console.log(this);
}
normalFunc1(); // Window

function normalFunc2() {
  function innerFunc() {
    console.log(this);
  }
  innerFunc();
}
normalFunc2(); // Window

// 메소드 내부의 일반 함수에서도 window
// 그러나 화살표 함수는 자동으로 외부 환경에 바인딩 되어 외부 환경이 this로 나온다.

const obj = {
  method: function() {
    function innerFunc() {
      console.log(this);
    }
    innerFunc();
  },
  secondMethod: function() {
    const arrowFunc = () => {
      console.log(this);
    }
    arrowFunc();
  }
}
obj.method();  // Window
obj.secondMethod(); // {e: ƒ, g: ƒ}

3. 메소드 호출에서의 this는 .(점) 앞에 있는 것. 즉, 메소드가 담긴 객체

const obj = {
  prop: 'Hello world',
  method: function() {
    console.log(this.prop);
  }
}
obj.method(); // Hello world

그러나 메소드 내부함수의 경우는 또 얘기가 달라진다. 이때는 일반 함수에서의 this와 마찬가지로 전역을 가리킨다.

var prop = 'This is window';

const obj = {
  prop: 'Bye world',
  method: function() {
    console.log(this.prop);

    function innerFunc() {
      console.log(this.prop);
    }
    innerFunc();
  }
}
obj.method(); // Bye world
              // This is window

위와 같은 문제에 대처하기 위한 방법으로 this를 변수에 할당하는 우회법이 있다. 그리고, 내부함수를 화살표 함수로 작성하면 외부환경인 메소드의 this를 그대로 바인딩한다.

const obj = {
  prop: 'Nice to meet you world',
  method: function() {
    // this를 that에 할당
    const that = this;
    function innerFunc() {
      console.log(that.prop);
    }
    innerFunc();
  },
  secondMethod: function() {
    const innerArrow = () => {
      console.log(this.prop);
    }
    innerArrow();
  }
}
obj.method(); // Nice to meet you world
obj.secondMethod(); // Nice to meet you world

4. 콜백에서의 this는 기본적으로는 일반 함수처럼 전역을 가리킨다

const obj = {
  prop: 'This is callback',
  method: function() {
    setTimeout(() => {
      console.log(this.prop);
    }, 1000);
  },
  secondMethod: function() {
    setTimeout(function() {
      console.log(this.prop);
    }.bind(obj), 1000); // <- binding
  }
}

// 화살표 함수로 작성하면 외부 환경에 바인딩
obj.method(); // This is callback
obj.secondMethod(); // This is callback

하지만, call, apply, bind 메서드를 통해 this를 명시적으로 바인딩 할 수 있다.

function a(x, y, z) {
  console.log(this, x, y, z);
}
var b = {
  c: 'Hello'
};
a.call(b, 1, 2, 3); // {c: "Hello"} 1 2 3
a.apply(b, [1, 2, 3]); // {c: "Hello"} 1 2 3

var c = a.bind(b);
c(1, 2, 3); // {c: "Hello"} 1 2 3

var d = a.bind(b, 1, 2);
d(3); // {c: "Hello"} 1 2 3

5. 생성자 함수에서의 this는 instance

class Animal {
  constructor(name, species) {
    this.name = name;
    this.species = species;
  }
}
Animal.prototype.whatIsThis = function() {
  console.log(this);
};

const dog = new Animal('Max', 'Dog');
dog.whatIsThis(); // Animal {name: "Max", species: "Dog"}

const cat = new Animal('Alice', 'Cat');
cat.whatIsThis(); // Animal {name: "Alice", species: "Cat"}

참고:

© 2023 intzzzero, Built with

Gatsby