본문 바로가기
JavaScript

[자바스크립트] 자바스크립트에서 this란?

by 메이플 🍁 2022. 11. 18.

this란?

자바스크립트에서 키워드 this는 해당 오브젝트를 가리킨다

  1. 전역공간 → window
  2. 일반 함수 호출시 → window
  3. 화살표 함수 호출시 → 상위 스코프
  4. 함수가 strict mode일때 → undefined
  5. 메소드 호출시 → 메소드를 부른 오브젝트
  6. call, apply, bind → call, apply, bind는 함수의 메소드로서 this를 첫번째 아규먼트와 바꿔치기한다 (함수의 호출방식과 관계없이 this를 지정할 수 있다)
  7. 콜백 호출시 → 경우에 따라 다르다
    • 일반적인 함수 호출일때: this는 전역객체
    • 함수 메소드 call, apply, bind를 사용할 경우: this는 바꿔치기 됨
  8. 생성자 함수 호출시 → 해당 인스턴스

 

this의 특징

  • 코드가 작성될때는 this가 어떤값인지 모른다
  • 프로그램 작동시 해당 함수가 호출될 때 this가 결정된다
  • this는 '누가 나를 불렀느냐'를 뜻한다
  • 선언이 아닌 호출에 따라 this가 가리키는 것이 달라진다

 

1. 전역 공간 (Global Scope)

→ 전역공간에서 this가 호출되면 window를 가리킨다

var a = 10
console.log(a) // 10
console.log(this.a)
// ** this가 호출된곳: 전역공간 **
// → this는 전역공간 window를 가리킨다
// window.a
// 10

 

2. 일반함수 호출시 (In a Function)

→ 일반함수에서 this가 호출되면 window를 가리킨다

var a = 10

function ex1() {
  console.log(this.a)
  // ** this가 호출된곳: 일반함수 **
  // → this는 전역공간 window를 가리킨다
  // window.a
  // 10
}

ex1()

 

3. Strict Mode 함수 호출시 (In a Strict Mode Function)

→ strict mode 함수에서 this가 호출되면 undefined를 가리킨다

"use strict"

function test() {
  console.log(this)
  // ** this가 호출된곳: strict 모드 함수 **
  // → this는 undefined를 가리킨다
  // undefined
}

test()

 

4. 메소드 호출시 (In a Method)

→ 메소드에서 this가 호출되면 caller(메소드를 부른 오브젝트)를 가리킨다

var a = 10

var obj = {
  a: 20,
  func: function() {
    console.log(this.a)
    // ** this가 호출된곳: caller(메소드를 부른 오브젝트) **
    // → this는 obj를 가리킨다
    // obj.a
    // 20
    function ex4() {
      console.log(this.a)
      // ** this가 호출된곳: 일반함수 **
      // → this는 전역공간 window를 가리킨다
      // window.a
      // 10
    }
    ex4()
  }
}

obj.func()

 

5. call / apply / bind

→ call, apply, bind는 함수의 메소드로서 this를 바꿔치기한다 (함수의 호출방식과 관계없이 this를 지정할 수 있다)

call

  • call은 보통함수와 똑같이 인수(argument)를 넣는다
  • call 메소드의 첫번째 아규먼트로 this를 교체할 데이터를 가진다
a.call(this를 교체할 데이터, par1, par2...)
function a(x, y, z) {
  console.log(this, x, y, z)
  // ** this가 호출된곳: call 메서드 **
  // → this는 call 메서드의 첫번째 인수를 가리킨다
  // b
  // { c: 'hello' }
}

var b = {
  c: 'hello'
}

a.call(b, 1, 2, 3)
// {c: 'hello'} 1 2 3

apply

  • apply는 인자를 하나로 묶어 배열로 만들어 넣는다
  • apply 메소드의 첫번째 아규먼트로 this를 교체할 데이터를 가진다
a.apply(this를 교체할 데이터, [par1, par2...])
function a(x, y, z) {
  console.log(this, x, y, z)
  // ** this가 호출된곳: apply 메서드 **
  // → this는 apply 메서드의 첫번째 인수를 가리킨다
  // b
  // { c: 'hello' }
}

var b = {
  c: 'hello'
}

a.apply(b, [1, 2, 3])
// { c: 'hello' } 1 2 3

bind

  • bind 함수는 함수가 가리키는 this만 바꾸고 호출하지는 않는다 (따로 호출 필요)
  • bind 메소드의 첫번째 아규먼트로 this를 교체할 데이터를 가진다
  • bind 메소드를 접목시킨 함수를 호출할때 다른 파라미터를 추가할 수 있다
a.bind(this를 교체할 데이터, par1, par2...) // 호출안함
function a(x, y, z) {
  console.log(this, x, y, z)
  // ** this가 호출된곳: bind 메서드 **
  // → this는 bind 메서드의 첫번째 인수를 가리킨다
  // b
  // { c: 'hello' }
}

var b = {
  c: 'hello'
}

a.bind(b, [1, 2, 3])
// 함수 a는 호출되지 않는다

var c = a.bind(b, 1, 2, 3)
c()
// 함수 c는 호출된다
// {c: 'hello'} 1 2 3

var d = a.bind(b, 1, 2)
d(3)
// 함수 d는 세번째 파라미터를 전달하면서 호출된다
// {c: 'hello'} 1 2 3

 

6. 콜백 호출시 (In a Callback)

→ 경우에 따라 다르다

  • 일반적인 함수 호출일때: this는 전역객체 가리킴
  • 함수 메소드 call, apply, bind를 사용할 경우: this는 바꿔치기 됨

일반적인 함수호출일때

var a = 2

function cb() {
  console.log(this.a)
  // ** this가 호출된곳: 일반함수 **
  // → this는 window
  // window.a
  // 2
}

cb()

call, apply, bind를 사용할 경우

function cb() {
  console.log(this.a);
  // ** this가 호출된곳: call 메서드 **
  // → this는 call 메서드의 첫번째 인수를 가리킨다
  // obj.a
  // 1
}

var obj = {
  a: 1,
  b: function(cb) {
  	cb()
  }
}

obj.b.call(obj, cb)

 

7. 생성자 함수 호출시 (In an Instance by New)

→ this는 해당 인스턴스를 가리킨다

  1. MyClass를 사용해 a라는 인스턴스(객체)를 만든다
  2. 새로운 생성자가 생겨났을때 ( new 클래스이름() ) 클래스 안에 있는 constructor가 실행이 된다
  3. 클래스 안에 있는 this는 해당 인스턴스(객체)를 가리키고 있다
  4. 즉 변수 apple에 들어있는 this는 클래스로 만들어진 인스턴스 객체 { a: 10 }를 가리키고 있다

인스턴스(instance)

  • 인스턴스는 클래스를 이용해 생성된 객체다
  • 인스턴스는 객체와 유사하지만 객체는 포괄적이고 일반적인 반면에 인스턴스는 클래스를 사용하여 만들어진 객체라는 의미가 강하다
  • 인스턴스는 클래스를 사용해 여러번 만들 수 있으며 데이터가 있기 때문에 메모리에 올라간다
  • 클래스를 사용해 만든 오브젝트이기 때문에 클래스가 가지고 있는 프로퍼티와 메소드를 모두 상속받는다
class MyClass {
  constructor() {
    this.a = 10
    console.log(this)
    // ** this가 호출된곳: 생성자 함수 **
    // → this는 해당 인스턴스 apple을 가리킨다
    // console.log(apple)
    // { a: 10 }
  }
}

var apple = new MyClass()

console.log(apple)

댓글