[JavaScript] This

/

This란?Permalink

자바스크립트에서 함수를 호출하면 그 함수에는 매개변수로 전달된 인자 외에 thisargument가 내부적으로 전달된다. 그리고 이때 this에 할당되는 값은 기본적으로 전역 객체, 즉 모든 객체의 유일한 최상위 객체인 window이며 이는 함수를 호출한 방식에 따라 동적으로 변하게 된다.

함수 호출 방식Permalink

함수 호출 방식에는 함수 호출, 메서드 호출, 그리고 생성자 함수 호출 등이 있다.

1. 함수 호출Permalink

전역 문맥에 선언한 함수는 전역 객체의 메서드라고 생각할 수 있다.

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

전역 문맥에서 선언한 함수의 this도 전역 객체인 window에 바인딩 된다.

function foo() {
  console.log(this);
}

foo(); // window

중첩된 함수에서 내부 함수의 this도 전역 객체인 window에 바인딩 된다.

function outer() {
  console.log("outer", this);

  function inner() {
    console.log("inner", this);
  }
  inner();
}

outer();
// "outer", window
// "inner", window

메서드의 내부 함수의 this도 전역 객체인 window에 바인딩 된다.

const value = "global";

const obj = {
  value: "local",
  method: function () {
    function inner() {
      console.log("inner", this);
      console.log("value", this.value);
    }
    inner();
  },
};

obj.method();
// "inner", window
// "value", "global"

콜백 함수의 this도 전역 객체의 window에 바인딩 된다.

const value = "global";

const obj = {
  value: "local",
  callback: function () {
    setTimeout(function () {
      console.log("callback", this);
      console.log("value", this.value);
    }, 1000);
  },
};

obj.callback();
// "callback", window
// "value", "global"

이렇듯 내부 함수의 this는 선언된 위치와 상관 없이 전역 객체 window에 바인딩 된다.

2. 메서드 호출Permalink

만약 함수가 메서드로써 호출이 된다면 this는 해당 메서드가 속한 객체에 바인딩 된다.

const value = "global";

const obj = {
  value: "local",
  method: function () {
    console.log("method", this);
    console.log("value", this.value);
  },
};

obj.method();
// "method", obj
// "value", "local"

3. 생성자 함수 호출Permalink

함수를 new 연산자와 함께 호출하여 해당 함수를 생성자 함수로 사용하면 this는 새로 생성한 객체에 바인딩 된다.

만약 생성자 함수에 반환문이 없는 경우, 반환문에 this를 적어준 것과 같은 동작을 하게 되어 this에 바인딩 된 새로 생성한 객체가 반환된다.

function Constructor(name) {
  this.name = name;
}

const moon = new Constructor("Moon");

console.log(moon); // { name: "Moon" }

만약 new 연산자와 함께 함수를 호출하지 않으면 이는 일반 함수가 되기 때문에 this가 전역 객체window에 바인딩 되어 작동이 달라진다.

function Constructor(name) {
  this.name = name;
}

const ga = Constructor("Ga");

console.log(ga); // undefined
console.log(window.name); // "Ga"

4. apply/call/bind 호출Permalink

앞서 언급한 방식들에 따라 this가 암묵적으로 바인딩 되는 것 대신에 이 값을 직접 명시하고 싶다면 applycall을 사용하면 된다.

applyPermalink

apply 메서드는 두 개의 매개변수를 사용하는데, 첫 번째 매개변수에는 함수의 this에 바인딩하고자 하는 객체를 입력하고 두 번째 매개변수에는 함수에 전달할 인자의 배열을 입력하면 된다.

const Constructor = function (name, age) {
  this.name = name;
  this.age = age;
};

const object = {};

Constructor.apply(object, ["Moon", 20]);

console.log(object); // { name: "Moon", age: 20 }

apply를 사용함으로써 Constructorthisobjectthis를 가리키게 되었고, 그에 따라 인자로 전달한 "Moon"20objectnameage에 할당되었다.

callPermalink

call 메서드는 apply 메서드와 기능은 거의 유사하지만 apply 메서드와 달리 매개변수로 배열이 아닌 목록이 전달된다.

const Constructor = function (name, age) {
  this.name = name;
  this.age = age;
};

const object = {};

Constructor.call(object, "Moon", 20);

console.log(object); // { name: "Moon", age: 20 }

마찬가지로 Constructorthisobjectthis를 가리키게 되어 objectnameage에 할당되었다.

bindPermalink

bind 메서드는 매개변수로 전달된 값이 메서드가 사용된 함수의 this에 바인딩 된 새로운 함수를 생성한다.

const user = {
  name: "moon",
  age: 20,
};

function info() {
  console.log(this.name);
  console.log(this.age);
}

const getUser = info.bind(user);

getUser(); // "moon" 20

user 객체의 값들이 info함수의 this에 바인딩 되어 getUser라는 새로운 함수를 생성한 것을 확인할 수 있다.

참고: MDN - this
참고: PoiemaWeb - 함수 호출 방식에 의해 결정되는 this

Categories:

Updated:

Published: