this

@choi2021 ยท December 09, 2022 ยท 10 min read

๐Ÿ‘‰ This

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ this๋Š” "๋™์ "์œผ๋กœ ์ •ํ•ด์ง„๋‹ค๋ผ๊ณ  ํ•œ๋‹ค. ๊ธฐ์กด ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด๋“ค๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ this์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด ๋ณด๋ ค ํ•œ๋‹ค.

๐Ÿ™‹โ€โ™‚๏ธ This๋ž€

this๋Š” ์ž์‹ ์ด ์†ํ•œ ๊ฐ์ฒด ๋˜๋Š” ๋งŒ๋“ค์–ด ์งˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ณ€์ˆ˜์ด๋‹ค. ์ดํ•ด๋ฅผ ์œ„ํ•ด ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ณด์ž

const square = {
  distance: 5,
  getArea() {
    return square.distance ** 2
  },
}

console.log(square.getArea())

square ๊ฐ์ฒด์˜ getArea ๋ฉ”์†Œ๋“œ๋Š” distance๋ฅผ ์ด์šฉํ•ด ๋„“์ด๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค. ์ด๋•Œ ์ค‘์š”ํ•œ ๊ฒƒ์€ square๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์†์„ฑ์ธ distance๊ฐ’์ด ํ•„์š”ํ•˜๋‹ค๋Š” ์ ์ด๋‹ค. ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•œ ๋ณ€์ˆ˜ square๋ฅผ ์ž…๋ ฅํ•˜๋ฉด distance๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ํ•ญ์ƒ ๊ฐ์ฒด๋ฅผ ์„ ์–ธํ•œ ์‹๋ณ„์ž๋ฅผ ์ด์šฉํ•œ๋‹ค๋ฉด ์˜ค์ง square๋ผ๋Š” ์ด๋ฆ„์˜ ๊ฐ์ฒด์—์„œ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋–จ์–ด์ง€๊ฒŒ ๋œ๋‹ค.

์ด๋Ÿฌํ•œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๊ณ ๋ คํ•ด ๊ฐ์ฒด๊ฐ€ ์–ด๋–ป๊ฒŒ ์„ ์–ธ๋˜๋Š”์ง€์— ์ƒ๊ด€์—†์ด, ์–ด๋–ค ์ด๋ฆ„์˜ ์ธ์Šคํ„ด์Šค์ธ์ง€ ์ƒ๊ด€์—†์ด ํ•ญ์ƒ ์ž๊ธฐ ์ž์‹ ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๊ฐ€ ๋ฐ”๋กœ this๋ผ๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

์œ„๋ฅผ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด, ์ƒ์„ฑ์žํ•จ์ˆ˜, class๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

const square1 = {
  distance: 5,
  getArea() {
    return this.distance ** 2
  },
}

function ProtoSquare(distance) {
  this.distance = distance
}
ProtoSquare.prototype.getArea = function () {
  return this.distance ** 2
}

const square2 = new ProtoSquare(5)
console.log(square2.getArea())

class ClassSquare {
  constructor(distance) {
    this.distance = distance
  }
  getArea() {
    return this.distance ** 2
  }
}

const square3 = new ClassSquare(5)
console.log(square3.getArea())

์ด๋Ÿฌํ•œ this๋Š” "์–ด๋–ป๊ฒŒ" ๊ฒฐ์ •๋˜๋Š” ๊ฑธ๊นŒ?

๐Ÿ‘ this๊ฐ€ ๊ฒฐ์ •๋˜๋Š” ๋ฐฉ์‹

this๋Š” ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋˜๋А๋ƒ์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋˜๋Š”๋ฐ, this ๋ฐ”์ธ๋”ฉ์—๋Š” 4๊ฐ€์ง€ ๊ทœ์น™์ด ์žˆ๋‹ค. 4๊ฐ€์ง€ ๊ทœ์น™์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

1) ๊ธฐ๋ณธ๋ฐ”์ธ๋”ฉ

๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋‚˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ œ์™ธํ•œ ํ•จ์ˆ˜๋“ค, ์ผ๋ฐ˜ํ•จ์ˆ˜๋กœ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ this๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ „์—ญ๊ฐ์ฒด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์ „์—ญ๊ฐ์ฒด๋Š” ๋ธŒ๋ผ์šฐ์ €๋ƒ Node.js๋ƒ์— ๋”ฐ๋ผ ๊ฐ๊ฐ window์™€ global์„ ์˜๋ฏธํ•œ๋‹ค. ๋ธŒ๋ผ์šฐ์ € ๊ธฐ์ค€์œผ๋กœ ์ „์—ญ๊ฐ์ฒด๋Š” window๋กœ ์„ค๋ช…์„ ์ง„ํ–‰ํ•˜๋ ค ํ•œ๋‹ค.

function hi() {
  console.log(this) //window ๋˜๋Š” global
}
hi()

์ด๋•Œ ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€ ์ค‘์ฒฉ ํ•จ์ˆ˜๋‚˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ์ผ๋ฐ˜ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋  ๊ฒฝ์šฐ์—๋„ ๋™์ผํ•˜๊ฒŒ ์ „์—ญ ๊ฐ์ฒด๋กœ this ๋ฐ”์ธ๋”ฉ์ด ๋œ๋‹ค.

var value = 1

const obj = {
  value: 100,
  foo() {
    setTimeout(function () {
      console.log(this) // window
      console.log(this.value) // 1
    }, 100)
  },
  too() {
    function bar() {
      console.log(this) // window
      console.log(this.value) // 1
    }
    bar()
  },
}

var value = 1

const obj = {
  value: 100,
  too() {
    "use strict"
    function bar() {
      console.log(this) // undefined
      console.log(this.value) // Uncaught TypeError: Cannot read properties of undefined
    }
    bar()
  },
}

obj.too()

์ด๋•Œ use strict๋กœ ์—„๊ฒฉ๋ชจ๋“œ๋ฅผ ์ ์šฉํ•˜๋ฉด ์ „์—ญ๊ฐ์ฒด๋Š” ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ์—์„œ ์ œ์™ธ๋˜์–ด this.value๋Š” ์—๋Ÿฌ๋ฅผ ๋˜์ง€๊ฒŒ ๋œ๋‹ค.

2) ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ

ํ˜ธ์ถœํ•  ๋•Œ์˜ ๊ฐ์ฒด์˜ ์กด์žฌ ์—ฌ๋ถ€์— ๋”ฐ๋ผ, this๋Š” ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์— ์†ํ•ด์ง€์ง€ ์•Š๊ณ , ํ˜ธ์ถœํ•œ ๊ฐ์ฒด, ์ปจํ…์ŠคํŠธ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค. ์ด๊ฒƒ์„ ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ์ด๋ผ ํ•˜๋Š”๋ฐ ์ดํ•ด๋ฅผ ์œ„ํ•ด ๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ๋ณด์ž.

const person = {
  name: "lee",
  getName() {
    return this.name
  },
}

console.log(person.getName()) //lee

const anotherPerson = {
  name: "kim",
}

anotherPerson.getName = person.getName
console.log(anotherPerson.getName()) //kim

const getName = person.getName
console.log(getName()) // window

์œ„์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด getName์ด ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๊ณณ์— ๋”ฐ๋ผ this๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค. ๊ฐ์ฒด์—์„œ ์„ ์–ธ๋œ this๋ผ๋ฉด ํ•ด๋‹น ๊ฐ์ฒด์™€ binding์ด ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ, ํ˜ธ์ถœํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ๋ˆ„๊ตฌ๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๋Š” ๋…๋ฆฝ์ ์ธ ์ปจํ…์ŠคํŠธ ๊ฐ์ฒด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๋Š” ํ•จ์ˆ˜์˜ ์ปจํ…์ŠคํŠธ๋Š” ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๋งŒ๋“ค์–ด์ง€๊ณ , ๋งŒ๋“ค์–ด์ง€๋Š” ๊ณผ์ •์—์„œ this๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋•Œ์˜ ์ปจํ…์ŠคํŠธ ๊ฐ์ฒด๊ฐ€ this์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.

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

var name = {
  text: "์˜์ค€",
  foo: foo,
}

var person = {
  text: "๊ฐ€์˜",
  name: name,
}

person.name.foo()

๋งŒ์•ฝ ์ค‘์ฒฉ๋œ ์ƒํƒœ์—์„œ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ฐ์ฒด, name์„ ์•”์‹œ์ ์œผ๋กœ ์ปจํ…์ŠคํŠธ ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ์–ด๋””์„œ ํ˜ธ์ถœํ•˜๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋ฉด ์˜ˆ์ธกํ•˜๊ธฐ ์–ด๋ ต๊ณ  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. this binding์„ ์šฐ๋ฆฌ๊ฐ€ ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ?

3) ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ

this binding์„ ๋ช…์‹œ์ ์œผ๋กœ ์ •ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์—๋Š” apply, call, bind ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

apply์™€ call

๋‘ ๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ๋Š” ์‚ฌ์šฉ ์‹œ ์ „๋‹ฌํ•œ ๊ฐ์ฒด๋ฅผ this์— ๋ฐ”์ธ๋”ฉํ•˜๊ณ , ํ˜ธ์ถœํ•œ๋‹ค. ๋‘๊ฐ€์ง€ ๋ฉ”์†Œ๋“œ์˜ ์ฐจ์ด์ ์€ ํ•จ์ˆ˜์— ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์— ์žˆ๋‹ค. apply๋Š” ๋ฐฐ์—ด๋กœ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•˜๊ณ  call์€ ํ•˜๋‚˜ ํ•˜๋‚˜์”ฉ ์ „๋‹ฌํ•˜๊ณ  ํ˜ธ์ถœํ•œ๋‹ค.

function getThisBinding() {
  console.log(arguments)
  return this
}

const thisArg = { a: 1 }
console.log(getThisBinding())
console.log(getThisBinding.apply(thisArg, [1, 2, 3])) //[1, 2, 3]
console.log(getThisBinding.call(thisArg, 1, 2, 3)) //[1,2,3]

bind

bind๋Š” this๋งŒ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ํ˜ธ์ถœ์€ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ฝœ๋ฐฑํ•จ์ˆ˜๋‚˜ ์ค‘์ฒฉํ•จ์ˆ˜๊ฐ€ ์ผ๋ฐ˜ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, this๊ฐ€ ๋‹ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ•ด๊ฒฐํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

const person = {
  name: "lee",
  foo(callback) {
    setTimeout(callback.bind(this), 100)
  },
}

person.foo(function () {
  console.log(this.name) //lee
})

4) new ๋ฐ”์ธ๋”ฉ

์ƒ์„ฑ์žํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.

function foo() {
  this.name = "์˜์ค€"
  this.callName = function () {
    console.log(this.name)
  }
}

const bar = {
  name: "์ฃผํฌ",
}

const x = new foo()
x.callName.bind(bar)
x.callName() // ์˜์ค€

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋งŒ๋“  x ๊ฐ์ฒด์— ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ์ธ bind๋กœ bar๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋ คํ–ˆ์ง€๋งŒ, new ๋ฐ”์ธ๋”ฉ์ด ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์•„ "์˜์ค€"์œผ๋กœ ๋‚˜์˜จ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ”ผ ์˜ˆ์™ธ์ ์ธ ๋ฐ”์ธ๋”ฉ: ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

์•ž์„œ ์„ค๋ช…ํ•œ this ๋ฐ”์ธ๋”ฉ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ž‘์šฉํ•œ๋‹ค.ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ this๋ฅผ ๊ฐ–์ง€ ์•Š์•„ ํ•จ์ˆ˜ ์„ ์–ธ ์‹œ์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ this๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค. ํ•ญ์ƒ this๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— callbackํ•จ์ˆ˜์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

function foo() {
  setTimeout(() => {
    console.log(this.name)
  }, 1000)
}

const bar = {
  name: "์˜์ค€",
}

foo.call(bar) // ์˜์ค€

์œ„์˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด setTimeOut ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ this๋Š” foo์˜ this๋ฅผ ์ฐธ์กฐํ•˜๋Š”๋ฐ ํ˜„์žฌ call์„ ์ด์šฉํ•ด bar๋กœ ๋ฐ”์ธ๋”ฉ๋˜์–ด ๊ฒฐ๊ณผ๊ฐ€ ์ฒ ์ˆ˜๋กœ ๋‚˜ํƒ€๋‚œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

const foo = {
  name: "์˜์ค€",
  bar: () => console.log(this.name),
}

foo.bar() // undefined

const boo = {
  name: "์˜์ค€",
  far() {
    console.log(this.name)
  },
}

boo.far() //์˜์ค€

ํ•˜์ง€๋งŒ ์ฃผ์˜ํ•  ์ ์€ ๋ฉ”์†Œ๋“œ๋ฅผ ํ™”์‚ดํ‘œํ•จ์ˆ˜๋กœ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด foo ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ this์ธ ์ „์—ญ๊ฐ์ฒด๋ฅผ bindingํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”์†Œ๋“œ๋Š” ๋ฉ”์†Œ๋“œ ์ถ•์•ฝ์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒŒ ๋‚ซ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ—ท๊ฐˆ๋ ธ๋˜ ๊ฒƒ์€ bar๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„๋กœ ์ƒ๊ฐํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€์˜€๋‹ค. ๋ฉ”์†Œ๋“œ๋Š” ๊ฒฐ๊ตญ ๊ฐ์ฒด์˜ ํ‚ค์™€ ์—ฐ๊ฒฐ๋œ ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๊ฐ’์ด๋ฏ€๋กœ ์ด๊ฒƒ ์ž์ฒด๊ฐ€ ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง€์ง„ ์•Š์•„ ์œ„์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๋งˆ์น˜๋ฉฐ

this ๋ฐ”์ธ๋”ฉ์€ ์˜ˆ์ƒ์น˜ ๋ชปํ•˜๋Š” ์—๋Ÿฌ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ ํ•œ๋ฒˆ ์ •๋ฆฌ๋ฅผ ํ•˜๊ณ  ๋„˜์–ด๊ฐ€์•ผ ํ–ˆ๋‹ค. ์•„์ง ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์—์„œ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์ด ์™œ ์ „์—ญ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š”์ง€ ์ž˜ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•„ ์ƒ์„ฑ์žํ•จ์ˆ˜์™€ prototype์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•˜๊ณ  ๋‹ค์‹œํ•œ๋ฒˆ ํ™•์ธ์„ ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

[์ฐธ๊ณ ]

๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋”ฅ๋‹ค์ด๋ธŒ this ๋ฐ”์ธ๋”ฉ

@choi2021
๋งค์ผ์˜ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ฐœ๋ฐœ์ผ์ง€์ž…๋‹ˆ๋‹ค.