๐Ÿ”— THIS BINDING[JS]

hoheesuยท2024๋…„ 2์›” 11์ผ

JavaScript

๋ชฉ๋ก ๋ณด๊ธฐ
6/8
post-thumbnail

โ˜€๏ธ THIS

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

this๋Š” ์‹คํ–‰์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๊ฒฐ์ •๋œ๋‹ค. ์ด๋ง์„ this๋ฅผ bindํ•œ๋‹ค๊ณ  ํ•ด์„œ ThisBinding์ด๋ผ๊ณ  ํ•˜๋Š”๊ฒƒ์ด๋‹ค.


1๏ธโƒฃ ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ

๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ์€ ์ „์—ญ๊ณต๊ฐ„์—์„œ์˜ this๋ฅผ ๋งํ•œ๋‹ค.
์ „์—ญ๊ณต๊ฐ„์—์„œ this๋Š” ์ „์—ญ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
๋Ÿฐํƒ€์ž„์— ๋”ฐ๋ผ this๋Š” window(๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ) ๋˜๋Š” global(node ํ™˜๊ฒฝ)์„ ๊ฐ๊ฐ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

์ด๋•Œ ์กฐ์‹ฌํ•ด์•ผ ๋ ๊ฒƒ์€ ์—„๊ฒฉ๋ชจ๋“œ(use strict)๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์ „์—ญ๊ฐ์ฒด๊ฐ€ ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ ๋Œ€์ƒ์—์„œ ์ œ์™ธ๋œ๋‹ค. ์ด ๊ฒฝ์šฐ์—๋Š” this๊ฐ€ ๋ฐ”์ธ๋”ฉ ๋  ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— undefined ๊ฐ’์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์ด๋ž€ javascript๋กœ ๋งŒ๋“ค์–ด๋‘” ํ”„๋กœ๊ทธ๋žจ์ด ๊ตฌ๋™์ค‘์ธ ํ™˜๊ฒฝ์„ ๋งํ•œ๋‹ค. htmlํŒŒ์ผ ์•ˆ์— ์ˆจ๊ฒจ๋‘์–ด ํฌ๋กฌ๋ธŒ๋ผ์šฐ์ € ๋“ฑ์—์„œ ์—ฐ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์ธ ๊ฒƒ์ด๋‹ค.
console.log(this); // ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ Window ๋‚˜ browser๊ฐ์ฒด๊ฐ€ ๋‚˜์˜จ๋‹ค.

๐Ÿ’ก node ํ™˜๊ฒฝ์—์„œ ์ „์—ญ์ฝ”๋“œ์— this๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ๋นˆ ๊ฐ์ฒด๊ฐ€ ๋‚˜์˜ค๊ฒŒ ๋œ๋‹ค. ์ด ๋นˆ ๊ฐ์ฒด๋Š” ์‚ฌ์‹ค ๋ชจ๋“ˆ ๊ฐ์ฒด์— ์žˆ๋Š” exports ๊ฐ์ฒด์™€ ์™„๋ฒฝํ•˜๊ฒŒ ๋™์ผํ•œ ๊ฐ์ฒด์ด๋‹ค.

  • Node JS ํ™˜๊ฒฝ์—์„œ this๊ฐ€ ๋‘ ๊ฐ€์ง€ ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.

ํ•จ์ˆ˜ ๋‚ด์—์„œ์˜ this

function sayHello() {
  console.log('Hello, ' + this.name); 
  // "this"๋Š” ์ „์—ญ ๊ฐ์ฒด(window)๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  // ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
}
sayHello();  

ํ•จ์ˆ˜์—์„œ this๋ฅผ ์ฐ์–ด๋ณด๋ฉด ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ๊ฐ์ฒด๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.


2๏ธโƒฃ ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ this!

โ˜… ๋ฉ”์„œ๋“œ๋กœ์„œ ํ˜ธ์ถœํ•  ๋•Œ ๊ทธ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ์˜ this

js์—์„œ ํ•จ์ˆ˜๋Š” ๋‹จ๋…์œผ๋กœ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ๋„ ํ˜ธ์ถœ์ด ๋œ๋‹ค. ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœ์ด ๋œ ๊ฒฝ์šฐ this๊ฐ€ ์  ๋ฐ”๋กœ ์•ž์— ์žˆ๋Š” ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๐Ÿ’ก ํ•จ์ˆ˜์™€ ๋ฉ”์„œ๋“œ๋Š” ์„œ๋กœ ๋น„์Šทํ•ด ๋ณด์ด์ง€๋งŒ ๋…๋ฆฝ์„ฑ์„ ๊ธฐ์ค€์œผ๋กœ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๊ทธ์ž์ฒด๋กœ ๋…๋ฆฝ์ ์ธ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋ฉ”์„œ๋“œ๋Š” ์ž์‹ ์„ ํ˜ธ์ถœํ•œ ๋Œ€์ƒ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋™์ž‘์„ ์ˆ˜ํ–‰ ํ•˜๋Š”๊ฒƒ์ด๋‹ค.
ํ˜ธ์ถœ ๋ฐฉ์‹์˜ ์ฐจ์ด : ํ•จ์ˆ˜() ? ๊ฐ์ฒด.๋ฉ”์„œ๋“œ()

๊ฐ์ฒด ๋ฉ”์„œ๋“œ๋‚ด์—์„œ์˜ this

const person = {
  name: 'John',
  greet: function() {
    console.log('Hello, ' + this.name); 
    // "this"๋Š” ํ˜„์žฌ ๊ฐ์ฒด(person)๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
	// ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— this๋Š” ํ•ด๋‹น ๊ฐ์ฒด(person)๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
  }
};
person.greet(); // ์ถœ๋ ฅ: "Hello, John"

ํ•จ์ˆ˜์—์„œ this๋ฅผ ์ฐ์–ด๋ณด๋ฉด ํ˜ธ์ถœ ์ฃผ์ฒด๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ๊ฐ์ฒด๊ฐ€ ์ถœ๋ ฅ๋˜๊ณ  ๊ฐ์ฒด ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ๋Š” ํ˜ธ์ถœ์ฃผ์ฒด(person{})๋ฅผ ๋ช…์‹œํ•˜์—ฌ ๊ฐ์ฒด๋‚ด์—์„œ ์ถœ๋ ฅ์ด ๋œ๋‹ค.

let obj1 = {
  outer: function () {
    console.log("outer", this);
    let innerFunc = function () {
      console.log("inner", this);
    };
    innerFunc(); //inner ์ „์—ญ๋ณ€์ˆ˜
    let obj2 = {
      innerMethod: innerFunc,
    };
    obj2.innerMethod(); // inner obj2
  },
};
obj1.outer(); // outer obj1

this ๋ฐ”์ธ๋”ฉ์— ๊ด€ํ•ด์„œ๋Š” ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋‹น์‹œ์˜ ์ฃผ๋ณ€ ํ™˜๊ฒฝ( ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์ธ์ง€, ํ•จ์ˆ˜ ๋‚ด๋ถ€์ธ์ง€ )์€ ์ค‘์š”ํ•˜์ง€ ์•Š๊ณ , ์˜ค์ง ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ๋ฌธ ์•ž์— ์  ๋˜๋Š” ๋Œ€๊ด„ํ˜ธ ํ‘œ๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€๊ฐ€ ๊ด€๊ฑด์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

โ˜… ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ๊ทธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this (1)

์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” ์ „๋‹ฌ์ธ์ž๋กœ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งํ•œ๋‹ค.

์ฝœ๋ฐฑํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ํ•ด๋‹น ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ๋ฐ›์€ ํ•จ์ˆ˜(๋ฉ”์„œ๋“œ)๊ฐ€ ์ •ํ•œ ๊ทœ์น™์— ๋”ฐ๋ผ ๊ฐ’์ด ๊ฒฐ์ •๋œ๋‹ค. ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋„ ํ•จ์ˆ˜๊ธฐ ๋•Œ๋ฌธ์— this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜์ง€๋งŒ, ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๋„˜๊ฒจ๋ฐ›์€ ํ•จ์ˆ˜์—์„œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์— ๋ณ„๋„๋กœ this๋ฅผ ์ง€์ •ํ•œ ๊ฒฝ์šฐ๋Š” ์˜ˆ์™ธ์ ์œผ๋กœ ๊ทธ ๋Œ€์ƒ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค. (Ex. addEventListener() )

// ๋ณ„๋„ ์ง€์ • ์—†์Œ : ์ „์—ญ๊ฐ์ฒด

setTimeout(function () { console.log(this) }, 300);
// ๋ณ„๋„ ์ง€์ • ์—†์Œ : ์ „์—ญ๊ฐ์ฒด
[1, 2, 3, 4, 5].forEach(function(x) {
  console.log(this, x);
});
// addListener ์•ˆ์—์„œ์˜ this๋Š” ํ•ญ์ƒ ํ˜ธ์ถœํ•œ ์ฃผ์ฒด์˜ element๋ฅผ returnํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Œ
// ๋”ฐ๋ผ์„œ this๋Š” button์„ ์˜๋ฏธํ•จ
document.body.innerHTML += '<button id="a">ํด๋ฆญ</button>';
document.body.querySelector('#a').addEventListener('click', function(e) {
  console.log(this, e);
});
  • โœ… setTimeout ํ•จ์ˆ˜, forEach ๋ฉ”์„œ๋“œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋Œ€์ƒ์ด ๋  this๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ`, this๋Š” ๊ณง window๊ฐ์ฒด
  • โœ… addEventListner ๋ฉ”์„œ๋“œ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ, ์ž์‹ ์˜ this๋ฅผ ์ƒ์†ํ•˜๋ฏ€๋กœ, this๋Š” addEventListner์˜ ์•ž๋ถ€๋ถ„(button ํƒœ๊ทธ)

โ˜… ์ฝœ๋ฐฑํ•จ์ˆ˜์—์„œ์˜ this(2)

๋งŒ์ผ ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ์•„๋ž˜โฌ‡๏ธ์™€ ๊ฐ™์€ ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด showReturnValue()ํ•จ์ˆ˜์—์„œ obj.name์ด ์ถœ๋ ฅ๋˜์•ผ ํ• ๊ฒƒ ๊ฐ™๋‹ค. ํ•˜์ง€๋งŒ undefined๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

const obj = {
  name: "hoheesu",
  getName() {
    return this.name;
  },
};

function showReturnValue(callBack) {
  console.log(callBack());
}

console.log(obj.getName()); //hoheesu
showReturnValue(obj.getName); //undefined


๋ถ„๋ช… obj.getName๊ณผ callBack์€ ์™„๋ฒฝํ•˜๊ฒŒ ๋™์ผํ•œ ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์„œ๋กœ์˜ ๊ฐ’์€ ๋‹ค๋ฅด๊ฒŒ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ ์ด์œ ๋Š” ์ ์—ฐ์‚ฐ์— ์žˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ ์—ฐ์‚ฐ์ด๋‚˜ ๋Œ€๊ด„ํ˜ธ์—ฐ์‚ฐ์„ ํ†ตํ•ด ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผ์„ ํ•˜๋ฉด ์ฐธ์กฐํƒ€์ž…์ด๋ผ๋Š” ํŠน๋ณ„ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค. < ์ฐธ์กฐํƒ€์ž…์€ JS๋ช…์„ธ์„œ์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ํƒ€์ž…์ด๋‹ค >

์ฐธ์กฐํƒ€์ž… : (base, name, strict)๋ฅผ ํ•จ๊ป˜ ๋„˜๊ฒจ์ฃผ๋Š” ํƒ€์ž…์ด๋‹ค.

obj.getName() ์ฒ˜๋Ÿผ ๋ฐ”๋กœ ํ˜ธ์ถœ์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์ฐธ์กฐ ํƒ€์ž…์„ ํ†ตํ•ด ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ์„ ํ•˜์ง€๋งŒ function showReturnValue(callBack) { callBack() } ์ฒ˜๋Ÿผ ๋ณต์ œํ•˜์—ฌ ๋‹ค๋ฅธ๋ณ€์ˆ˜์— ๊ฐ’์„ ๋‹ด๋Š”๋‹ค๋ฉด ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๊ฐ’๋งŒ ๋‚จ๊ฒŒ ๋œ๋‹ค.
โ˜ž ์ ์—ฐ์‚ฐ์„ ํ†ตํ•ด ์–ป์€ ๊ฐ’์„ ๋ฐ”๋กœ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์—†๋‹ค.
์ด๋ ‡๋“ฏ ๋ณต์ œ๋ฅผ ๊ฑฐ์นœ๋‹ค๋ฉด ๋ฐ”์ธ๋”ฉ๋œ this๋ฅผ ์‰ฝ๊ฒŒ ์žƒ์–ด๋ฒ„๋ฆฌ๋Š” ๋ฌธ์ œ๋•Œ๋ฌธ์— ๋ช…์‹œ์ ์œผ๋กœ ThisBinding์„ ํ• ์ˆ˜์žˆ๋Š” ๋ฐฉ๋ฒ•๋“ค์ด ์žˆ๋‹ค
ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•.


3๏ธโƒฃ ๋ช…์‹œ์  this ๋ฐ”์ธ๋”ฉ

ํ•จ์ˆ˜๊ฐ์ฒด๋Š” call() / apply() / bind() ๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ์ž๋™์œผ๋กœ ๋ถ€์—ฌ๋˜๋Š” ์ƒํ™ฉ๋ณ„ this์˜ ๊ทœ์น™์„ ๊นจ๊ณ  this์— ๋ณ„๋„์˜ ๊ฐ’์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

โ˜… call() / apply() ๋ฉ”์„œ๋“œ

call()๊ณผ apply()๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ this๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ๋‘ ๋ฉ”์„œ๋“œ๋Š” ๊ฑฐ์˜ ๋™์ผํ•˜์ง€๋งŒ, ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฐ์ฒด์˜ ์ธ์ž๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋Š”๋ฐ(e.g. ์ƒ์„ฑ์ž์˜ ๋งค๊ฐœ๋ณ€์ˆ˜), call์€ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋ชฉ๋ก, apply๋Š” ๋ฐฐ์—ด์„ ๋ฐ›๋Š”๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ๋‹ค.

์‚ฌ์šฉ๋ฐฉ๋ฒ• ์˜ˆ์‹œ)

// ์ „์—ญ๊ฐ์ฒด๋ฅผ ๋ฐ”๋ผ๋ณด๋Š” ํ˜„์ƒ์—์„œ ๋ช…์‹œ์  binding
let func = function (a, b, c) {
  console.log(this, a, b, c);
};
func.call({ x: 1 }, 4, 5, 6); // { x: 1 } 4 5 6
func.apply({ x: 1 }, [4, 5, 6]); // { x: 1 } 4 5 6

// ํ˜ธ์ถœ์ฃผ์ฒด๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋ช…์‹œ์  binding
let obj = {
  a: 1,
  method: function (x, y) {
    console.log(this.a, x, y);
  },
};
obj.method.call({ a: 1 }, 5, 6); // 4 5 6
obj.method.apply({ a: 1 }, [5, 6]); // 4 5 6

โ˜… call() apply() ์‚ฌ์šฉ ์˜ˆ์ œ

call()๊ณผ apply()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ์ž ๋‚ด๋ถ€์—์„œ ๋‹ค๋ฅธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ(๊ณตํ†ต๋œ ๋‚ด์šฉ์˜ ๋ฐ˜๋ณต ์ œ๊ฑฐ)ํ•  ์ˆ˜ ์žˆ๋‹ค.

function Person(name, gender) {
  this.name = name;
  this.gender = gender;
}
function Student(name, gender, school) {
	Person.call(this, name, gender); // ์—ฌ๊ธฐ์„œ this๋Š” student ์ธ์Šคํ„ด์Šค!
  this.school = school;
}
function Employee(name, gender, company) {
  Person.apply(this, [name, gender]); // ์—ฌ๊ธฐ์„œ this๋Š” employee ์ธ์Šคํ„ด์Šค!
  this.company = company;
}
let kd = new Student('๊ธธ๋™', 'male', '์„œ์šธ๋Œ€');
let ks = new Employee('๊ธธ์ˆœ', 'female', '์‚ผ์„ฑ');

โฌ†๏ธ์œ„ ์ฝ”๋“œ์—์„œ Student, Employee๋Š” ๋ชจ๋‘ name๊ณผ gender ๊ฐ€ ํ•„์š”ํ•œPerson์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ Student์™€ Employee ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ๋งˆ๋‹ค ์„ธ ๊ฐ€์ง€ ์†์„ฑ์„ ๋ชจ๋‘ ๊ฐ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ๋„ฃ๊ธฐ ๋ณด๋‹ค๋Š” Person์ด๋ผ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๋ณ„๋„๋กœ ๋นผ๋Š”๊ฒŒ ๊ตฌ์กฐํ™”์— ๋„์›€์ด ๋” ๋œ๋‹ค.

โ˜… bind ๋ฉ”์„œ๋“œ

call๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ฆ‰์‹œ ํ˜ธ์ถœํ•˜์ง€๋Š” ์•Š๊ณ  ๋„˜๊ฒจ๋ฐ›์€ this ๋ฐ ์ธ์ˆ˜๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

โœ… ํ•จ์ˆ˜์— this๋ฅผ ๋ฏธ๋ฆฌ ์ ์šฉํ•œ๋‹ค
โœ… ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜ ๊ตฌํ˜„ํ•  ๋•Œ ์šฉ์ดํ•˜๋‹ค.

// ํ•จ์ˆ˜์— this ๋ฏธ๋ฆฌ ์ ์šฉ
let func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
let bindFunc1 = func.bind({ x: 1 }); // ๋ฐ”๋กœ ํ˜ธ์ถœ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. 
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8
// ๋ถ€๋ถ„ ์ ์šฉ ํ•จ์ˆ˜ ๊ตฌํ˜„ 
let bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4์™€ 5๋ฅผ ๋ฏธ๋ฆฌ ์ ์šฉ
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9

console.log(func.name); // func
console.log(bindFunc1.name); // bound func
console.log(bindFunc1.name); // bound func

bind ๋ฉ”์„œ๋“œ๋ฅผ ์ ์šฉํ•ด์„œ ์ƒˆ๋กœ ๋งŒ๋“  ํ•จ์ˆ˜๋Š” name ํ”„๋กœํผํ‹ฐ์— โ€˜bound funcโ€™ ๋ผ๋Š” ์ ‘๋‘์–ด์ธ nameํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ถ™๋Š”๋‹ค. โžก๏ธ ์ดํ›„์— ํ•จ์ˆ˜๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์‰ฝ๋‹ค.

let func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
let bindFunc = func.bind({ x:1 }, 4, 5);
// func์™€ bindFunc์˜ name ํ”„๋กœํผํ‹ฐ์˜ ์ฐจ์ด๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”!
console.log(func.name); // func
console.log(bindFunc.name); // bound func

โ˜… ์ฝœ๋ฐฑํ•จ์ˆ˜์—์„œ ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ

๊ทธ๋ ‡๋‹ค๋ฉด โฌ†๏ธ์œ„์— ์žˆ๋˜ ์ฝœ๋ฐฑํ•จ์ˆ˜์—์„œ์˜ ๋ฐ”์ธ๋”ฉ ๋ฌธ์ œ ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ฝ”๋“œ๋กœ ์ž‘์„ฑ์„ ํ•ด๋ณด์ž๋ฉด,

โ˜† call๊ณผ apply๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•˜๊ธฐ

const obj = {
  name: "hoheesu",
  getName() {
    return this.name;
  },
};

function showReturnValue(callBack) {
  console.log(callBack.call(obj)); // console.log(callBack.apply(obj));
}

showReturnValue(obj.getName); //undefined

์ด๋Ÿฐ์‹์œผ๋กœ call๊ณผ apply๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฐ”์ธ๋”ฉ์„ ํ•ด์ค„๋•Œ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐ”์ธ๋”ฉ์„ ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

โ˜† bind๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•˜๊ธฐ

const obj = {
  name: "hoheesu",
  getName() {
    return this.name;
  },
};

function showReturnValue(callBack) {
  console.log(callBack());
}

const boundGetName = obj.getName.bind(obj);
showReturnValue(boundGetName); //undefined

bind๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ช…์‹œ์  this๋ฐ”์ธ๋”ฉ์„ ํ•  ๋•Œ๋Š” ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ํ˜ธ์ถœํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด this ๋ฐ”์ธ๋”ฉ์„ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

4๏ธโƒฃ new ๋ฐ”์ธ๋”ฉ

JavaScript์—์„œ ํ•จ์ˆ˜๋ฅผ new ์—ฐ์‚ฐ์ž๋กœ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ์„œ์˜ ์—ญํ• ์„ ํ•จ์ˆ˜๊ฐ€ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
์•„์ฃผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด new์—ฐ์‚ฐ์ž๋กœ ํ˜ธ์ถœํ•˜๊ฒŒ๋˜๋ฉด โžก๏ธ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ โžก๏ธ ํ•จ์ˆ˜์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ โžก๏ธ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ ์ด ๊ณผ์ •์—์„œ this๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋ ๋•Œ binding๋œ๋‹ค.

์ฝ”๋“œ๋กœ ํ‘œํ˜„์„ ํ•œ๋‹ค๋ฉด โฌ‡๏ธ์•„๋ž˜์‚ฌ์ง„์ฒ˜๋Ÿผ ์ž‘์„ฑ ํ•  ์ˆ˜ ์žˆ์„๊ฒƒ์ด๋‹ค.

โœ… ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ์˜ this๋Š” ํ•ญ์ƒ ์ธ์Šคํ„ด์Šค๋ฅผ ์ง€์นญํ•œ๋‹ค.

const Cat = function (name, age) {
  this.bark = "์•ผ์˜น";
  this.name = name;
  this.age = age;
};

const choco = new Cat("์ดˆ์ฝ”", 7); //this : choco
const nabi = new Cat("๋‚˜๋น„", 5); //this : nabi

โฌ†๏ธ ์œ„ ์ฝ”๋“œ์—์„œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” function (name, age){ ... } ๋ถ€๋ถ„์ด๋‹ค. ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค(์œ„ ์ฝ”๋“œ์—์„œ๋Š” choco์™€ nabi )๋ฅผ ์ง€์นญํ•œ๋‹ค.

๋งŒ์ผ ํ•จ์ˆ˜๊ฐ€ ์ค‘๋ณตํ•ด์„œ ๋ฐ”์ธ๋”ฉ์„ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด
New ๋ฐ”์ธ๋”ฉ > ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ > ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ > ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ
์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.

5๏ธโƒฃ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

ES6์—์„œ ์ฒ˜์Œ ๋„์ž…๋œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š”, ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ this ๋ฐ”์ธ๋”ฉ ๊ณผ์ • ์ž์ฒด๊ฐ€ ์—†๋‹ค. this๋ฐ”์ธ๋”ฉ ์ž์ฒด๊ฐ€ ์—†๋‹ค๋Š” ๋ง์€ : <this ์ด์ „์˜ ๊ฐ’-์ƒ์œ„๊ฐ’-์ด ์œ ์ง€๋œ๋‹ค>๋Š” ๊ฒƒ์ด๋‹ค.
ES6์—์„œ๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ this๊ฐ€ ์ „์—ญ๊ฐ์ฒด๋ฅผ ๋ฐ”๋ผ๋ณด๋Š” ๋ฌธ์ œ ๋•Œ๋ฌธ์— ํ™”์‚ดํ‘œํ•จ์ˆ˜๋ฅผ ๋„์ž…ํ•œ ๊ฒƒ์ด๋‹ค.

์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด์ ์€ this binding ์—ฌ๋ถ€์ด๋‹ค.

let obj = {
  outer: function () {
    let innerFunc1 = () => {
      console.log("innerFnc1", this);
    };
    innerFunc1(); // innerFnc1 { outer: [Function: outer] }
    function innerFunc2() {
      console.log("innerFnc2", this);
    }
    innerFunc2(); //innerFnc2 global{}
  },
};

obj.outer();

โฌ†๏ธ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ this๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ž์‹ ์˜ ์ƒ์œ„๊ฐ’์ธ outer๊ฐ€ ๋ฐ”๋กœ ์ถœ๋ ฅ๋˜์ง€๋งŒ ๊ธฐ๋ณธ ํ•จ์ˆ˜ ์„ ์–ธ์‹์œผ๋กœ this๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ „์—ญ๊ฐ์ฒด๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

6๏ธโƒฃ ๊ทธ์™ธ this ์šฐํšŒ๋ฐฉ๋ฒ•

โ˜… ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

๋‚ด๋ถ€ ์Šค์ฝ”ํ”„์— ์ด๋ฏธ ์กด์žฌํ•˜๋Š” this๋ฅผ ๋ณ„๋„์˜ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๋Š” ๋ฐฉ์‹

  • ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜ ๋ช…์€ _this, that, self ๋“ฑ์ด ์žˆ๋‹ค.
let obj1 = {
  outer: function () {
    console.log("outer", this); // outer { outer: [Function: outer] }
    let self = this;
    console.log("self", this); // self { outer: [Function: outer] }
    let innerFnc = function () {
      console.log("inner", self); // inner { outer: [Function: outer] }
    };
    innerFnc();
  },
};
obj1.outer();

โฌ†๏ธ ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ self๋ผ๋Š” ๋ณ€์ˆ˜์— this๋ฅผ ํ• ๋‹นํ•จ์œผ๋กœ์จ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ• ๋•Œ ๋ ‰์‹œ์ปฌ์Šค์ฝ”ํ”„์— ์˜ํ•ด self์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ๋˜๊ณ , self๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๋Š” ์ƒ์œ„ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

๐Ÿงน ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์ •๋ฆฌ

const outer = {
  name: "hoheesu",
  innerFnc: function () {
    setTimeout(function () {
      console.log(this.name);
    }, 1);
  },
};
outer.innerFnc(); //undefined

โฌ†๏ธ ์œ„ ์ฝ”๋“œ๋Š” undefined๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ์ฝ”๋“œ์ด๋‹ค. setTimeout์— ์ฝœ๋ฐฑ์œผ๋กœ ๋„˜๊ฒจ์ง„ ํ•จ์ˆ˜์˜ this๋Š” setTimeout์— ์˜ํ•ด ์‹คํ–‰๋ ๋•Œ ์ „์—ญ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฝœ๋ฐฑ ๋‚ด๋ถ€์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ์‹์€ ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์žˆ๋‹ค.

โ‘  ํ™”์‚ดํ‘œํ•จ์ˆ˜

const obj = {
  name: "hoheesu",
  logThisLater: function () {
    setTimeout(() => {
      console.log(this.name);
    }, 100);
  },
};

obj.logThisLater();

โ‘ก ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉ

const obj = {
  name: "hoheesu",
  logThisLater: function () {
    const _this = this;
    setTimeout(function () {
      console.log(_this.name);
    }, 100);
  },
};

obj.logThisLater();

์ฐธ๊ณ ๋ฌธํ—Œ
[10๋ถ„ ํ…Œ์ฝ”ํ†ก] ๐Ÿฅฆ ๋ธŒ์ฝœ์˜ This

profile
๐Ÿค”๐Ÿ‘๐Ÿ’ก๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป๐Ÿคฏ๐Ÿ˜‡

0๊ฐœ์˜ ๋Œ“๊ธ€