Skip to content

Latest commit

ย 

History

History
510 lines (396 loc) ยท 16.4 KB

File metadata and controls

510 lines (396 loc) ยท 16.4 KB

22.1 this

  • ๊ฐ์ฒด๋Š” ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๋™์ž‘์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜๋‚˜์˜ ๋…ผ๋ฆฌ์ ์ธ ๋‹จ์œ„๋กœ ๋ฌถ์€ ๋ณตํ•ฉ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.
  • ๋™์ž‘์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฉ”์„œ๋“œ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•จ. ๋ฉ”์„œ๋“œ๊ฐ€ ์ž์‹ ์ด ์†ํ•œ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ์ž์‹ ์ด ์†ํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์‹๋ณ„์ž๋ฅผ ์ฐธ์กฐ ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค.
const circle = {
  // โœ… ํ”„๋กœํผํ‹ฐ: ๊ฐ์ฒด ๊ณ ์œ ์˜ ์ƒํƒœ ๋ฐ์ดํ„ฐ
  radius: 5,
  // โœ… ๋ฉ”์„œ๋“œ: ์ƒํƒœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์กฐ์ž‘ํ•˜๋Š” ๋™์ž‘
  getDiameter() {
    // this๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    return 2 * this.radius;
  },
};

console.log(circle.getDiameter()); // 10

๐Ÿšจ ์ž๊ธฐ ์ž์‹ ์ด ์†ํ•œ ๊ฐ์ฒด๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ์ฐธ์กฐํ•˜๋Š” ๋ฐฉ์‹์€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๋‹ค.
๐Ÿ‘‰ ๋Œ€์‹ , ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋ฐฉ์‹์œผ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ์ฐจ์šฉ

  • this๋Š” ์ž์‹ ์ด ์†ํ•œ ๊ฐ์ฒด ๋˜๋Š” ์ž์‹ ์ด ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ž๊ธฐ ์ฐธ์กฐ ๋ณ€์ˆ˜๋กœ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • this๋Š” ์—”์ง„์— ์˜ํ•ด ์•”๋ฌต์ ์œผ๋กœ ์ƒ์„ฑ๋˜๊ณ  ์–ด๋””์„œ๋“  ์ฐธ์กฐ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ arguments ๊ฐ์ฒด์™€ this๊ฐ€ ์•”๋ฌต์ ์œผ๋กœ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ์ „๋‹ฌ๋˜์–ด, ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋„ arguments ๊ฐ์ฒด๋ฅผ ์ง€์—ญ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์“ฐ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด this๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ๐Ÿ‘‰ this ๋ฐ”์ธ๋”ฉ(this๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ’)์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐฉ์‹์— ์˜ํ•ด ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋จ.
  • strict mode ์ ์šฉ์‹œ, ์ผ๋ฐ˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์—๋Š” undefined๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค. => this๋Š” ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€ ๋˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ..
// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Circle(radius) {
  // this๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  this.radius = radius;
}

Circle.prototype.getDiameter = function () {
  // this๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  return 2 * this.radius;
};

// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const circle = new Circle(5);
console.log(circle.getDiameter()); // 10
// this๋Š” ์–ด๋””์„œ๋“ ์ง€ ์ฐธ์กฐ ๊ฐ€๋Šฅํ•˜๋‹ค.
// ์ „์—ญ์—์„œ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
console.log(this); // window

function square(number) {
  // ์ผ๋ฐ˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  console.log(this); // window
  return number * number;
}
square(2);

const person = {
  name: "Lee",
  getName() {
    // ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ this๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    console.log(this); // {name: "Lee", getName: ฦ’}
    return this.name;
  },
};
console.log(person.getName()); // Lee

function Person(name) {
  this.name = name;
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ this๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  console.log(this); // Person {name: "Lee"}
}

const me = new Person("Lee");

โ“๋ฐ”์ธ๋”ฉ์ด๋ž€

  • ์‹๋ณ„์ž์™€ ๊ฐ’์„ ์—ฐ๊ฒฐํ•˜๋Š” ๊ณผ์ •
  • this์™€ this๊ฐ€ ๊ฐ€๋ฆฌํ‚ฌ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๊ฒƒ

22.2 ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐฉ์‹๊ณผ this ๋ฐ”์ธ๋”ฉ

this ๋ฐ”์ธ๋”ฉ์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐฉ์‹, ์ฆ‰ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋œ๋‹ค.

๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„:

  • ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์œ„์น˜์—์„œ ๊ฒฐ์ •๋˜๋Š” ์Šค์ฝ”ํ”„
  • ํ•จ์ˆ˜๊ฐ€ ์–ด๋””์—์„œ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๊ฐ€ ์•„๋‹ˆ๋ผ ์–ด๋””์—์„œ ์ •์˜๋˜์—ˆ๋Š”์ง€์— ๋”ฐ๋ผ ๋ณ€์ˆ˜์˜ ์Šค์ฝ”ํ”„(์œ ํšจ ๋ฒ”์œ„)๊ฐ€ ๊ฒฐ์ •๋œ๋‹ค.

this ๋ฐ”์ธ๋”ฉ:

  • ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๋™์  ๋ฐ”์ธ๋”ฉ์„ ๊ฐ€์ง. (๋ฐ”์ธ๋”ฉ์€ ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๊ฐ’๊ณผ ์‹๋ณ„์ž ์‚ฌ์ด์˜ ์—ฐ๊ด€ ๊ด€๊ณ„)
  • this๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๋Š” ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ๊ฒฐ์ •๋œ๋‹ค.

๐Ÿ‘‰ ๋™์ผํ•œ ํ•จ์ˆ˜๋ฅผ ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๋‹ค.

22.2.1 ์ผ๋ฐ˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ

  • ๊ธฐ๋ณธ์ ์œผ๋กœ this์—๋Š” ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋˜๋Š”๋ฐ, ์ค‘์ฒฉ ํ•จ์ˆ˜๋ฅผ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•˜๋ฉด ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์—๋Š” ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.

  • this๋Š” ์ž๊ธฐ ์ฐธ์กฐ ๋ณ€์ˆ˜์ด๋ฏ€๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜์—์„œ๋Š” ์˜๋ฏธ๊ฐ€ ์—†๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, strict mode์—์„œ๋Š” undefined๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.

function foo() {
  "use strict";

  console.log("foo's this: ", this); // undefined
  function bar() {
    console.log("bar's this: ", this); // undefined
  }
  bar();
}
foo();
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ ์‹œ, ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์—๋„ ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค. ์–ด๋– ํ•œ ํ•จ์ˆ˜๋ผ๋„ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ ์‹œ, this์— ์ „์—ญ ๊ฐ์ฒด(window)๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
// var ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•œ ์ „์—ญ ๋ณ€์ˆ˜ value๋Š” ์ „์—ญ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋‹ค.
var value = 1;
// const ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•œ ์ „์—ญ ๋ณ€์ˆ˜ value๋Š” ์ „์—ญ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋‹ค.
// const value = 1;

const obj = {
  value: 100,
  foo() {
    console.log("foo's this: ", this); // {value: 100, foo: ฦ’}
    console.log("foo's this.value: ", this.value); // 100

    // ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ์ •์˜ํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜
    function bar() {
      console.log("bar's this: ", this); // window
      console.log("bar's this.value: ", this.value); // 1
    }

    // ๋ฉ”์„œ๋“œ ๋‚ด์—์„œ ์ •์˜ํ•œ ์ค‘์ฒฉ ํ•จ์ˆ˜๋„ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜๋ฉด ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์—๋Š” ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
    bar();
  },
};

obj.foo();
  • ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋œ ๋ชจ๋“  ํ•จ์ˆ˜(์ค‘์ฒฉ ํ•จ์ˆ˜, ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํฌํ•จ) ๋‚ด๋ถ€์˜ this์—๋Š” ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค. โš ๏ธ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋  ๋•Œ, ๋ฉ”์„œ๋“œ ๋‚ด ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ this๊ฐ€ ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Œ. ์™ธ๋ถ€ ํ•จ์ˆ˜์ธ ๋ฉ”์„œ๋“œ์™€ ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ this๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ๋•Œ, ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ—ฌํผ ํ•จ์ˆ˜๋กœ ๋™์ž‘ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค ์ˆ˜๊ฐ€ ์žˆ์Œ.
var value = 1;

const obj = {
  value: 100,
  foo() {
    console.log("foo's this: ", this); // {value: 100, foo: ฦ’}
    // ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์—๋Š” ์ „์—ญ ๊ฐ์ฒด๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
    setTimeout(function () {
      console.log("callback's this: ", this); // window
      console.log("callback's this.value: ", this.value); // 1
    }, 100);
  },
};

obj.foo();

setTime()

  • ๋‘๋ฒˆ์จฐ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ์‹œ๊ฐ„(ms)๋งŒํผ ๋Œ€๊ธฐํ•œ ๋‹ค์Œ, ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํƒ€์ด๋จธ ํ•จ์ˆ˜
  1. this๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ ์˜ˆ์ œ
const obj = {
  name: "Alice",
  showName: function () {
    console.log("๋ฉ”์„œ๋“œ ๋‚ด๋ถ€ this.name:", this.name); // "Alice"

    function innerFunction() {
      console.log("์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€ this.name:", this.name); // undefined (strict mode) ๋˜๋Š” window.name
    }

    innerFunction(); // ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋˜๋ฏ€๋กœ `this`๊ฐ€ ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด
  },
};

obj.showName();
  1. ์ฝœ๋ฐฑ ํ•จ์ˆ˜์—์„œ this ๋ฌธ์ œ
const obj = {
  name: "Alice",
  showName: function () {
    setTimeout(function () {
      console.log("setTimeout ๋‚ด๋ถ€ this.name:", this.name); // undefined
    }, 1000);
  },
};

obj.showName();

๐Ÿ‘‰ ํ•ด๊ฒฐ์ฑ… 1. self(or that) ๋ณ€์ˆ˜ ์‚ฌ์šฉ

  • self์— this(ํ˜„์žฌ ๊ฐ์ฒด)๋ฅผ ์ €์žฅํ•˜๊ณ  ์ค‘์ฒฉ ํ•จ์ˆ˜์—์„œ self๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด ์†์„ฑ์— ์ ‘๊ทผ
const obj = {
  name: "Alice",
  showName: function () {
    const self = this; // `this`๋ฅผ ์ €์žฅ
    function innerFunction() {
      console.log("์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€ this.name:", self.name); // "Alice"
    }
    innerFunction();
  },
};

obj.showName();

ํ•ด๊ฒฐ์ฑ… 2. bind() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ

const obj = {
  name: "Alice",
  showName: function () {
    function innerFunction() {
      console.log("์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€ this.name:", this.name); // "Alice"
    }

    const boundInnerFunction = innerFunction.bind(this); // `this`๋ฅผ obj๋กœ ๊ณ ์ •
    boundInnerFunction();
  },
};

obj.showName();

ํ•ด๊ฒฐ์ฑ… 3. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์‚ฌ์šฉ

  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” this๋ฅผ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ this๋ฅผ ๊ทธ๋Œ€๋กœ ๊ณ„์Šนํ•˜๋ฏ€๋กœ, ์ค‘์ฒฉ ํ•จ์ˆ˜์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.
const obj = {
  name: "Alice",
  showName: function () {
    const innerFunction = () => {
      console.log("์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€ this.name:", this.name); // "Alice"
    };
    innerFunction();
  },
};

obj.showName();

ํ•ด๊ฒฐ์ฑ… 4. call() ๋˜๋Š” apply() ์‚ฌ์šฉ

  • this๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ํ˜ธ์ถœ
const obj = {
  name: "Alice",
  showName: function () {
    function innerFunction() {
      console.log("์ค‘์ฒฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€ this.name:", this.name); // "Alice"
    }
    innerFunction.call(this); // `this`๋ฅผ obj๋กœ ์„ค์ •
  },
};

obj.showName();

22.2.2 ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ

  • ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์˜ this๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด(๋ฉ”์„œ๋“œ ์ด๋ฆ„ ์•ž์˜ ๋งˆ์นจํ‘œ(.) ์—ฐ์‚ฐ์ž ์•ž์— ๊ธฐ์ˆ ํ•œ ๊ฐ์ฒด)๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค. ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์˜ this๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์†Œ์œ ํ•œ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
const person = {
  name: "Lee",
  getName() {
    // ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์˜ this๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
    return this.name;
  },
};

// ๋ฉ”์„œ๋“œ getName์„ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋Š” person์ด๋‹ค.
console.log(person.getName()); // Lee


  • getName ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•จ์ˆ˜์ธ getName ๋ฉ”์„œ๋“œ๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Œ. ๋˜ํ•œ, ์ผ๋ฐ˜ ํ•จ์ˆ˜์— ํ• ๋‹นํ•˜์—ฌ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋  ์ˆ˜๋„ ์žˆ์Œ.
  • ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์˜ this๋Š” ํ”„๋กœํผํ‹ฐ๋กœ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์™€ ๊ด€๊ณ„๊ฐ€ ์—†๊ณ  ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ๋จ.
const anotherPerson = {
  name: "Kim",
};
// getName ๋ฉ”์„œ๋“œ๋ฅผ anotherPerson ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ ํ• ๋‹น
anotherPerson.getName = person.getName;

// getName ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋Š” anotherPerson์ด๋‹ค.
console.log(anotherPerson.getName()); // Kim

// getName ๋ฉ”์„œ๋“œ๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹น
const getName = person.getName;

// getName ๋ฉ”์„œ๋“œ๋ฅผ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ
console.log(getName()); // ''
// ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋œ getName ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this.name์€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ window.name๊ณผ ๊ฐ™๋‹ค.
// ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ window.name์€ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋นŒํŠธ์ธ ํ”„๋กœํผํ‹ฐ์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์€ ''์ด๋‹ค.
// Node.js ํ™˜๊ฒฝ์—์„œ this.name์€ undefined๋‹ค.


  • ํ”„๋กœํ† ํƒ€์ž… ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ๋œ this๋„ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
function Person(name) {
  this.name = name;
}

Person.prototype.getName = function () {
  return this.name;
};

const me = new Person("Lee");

// getName ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋Š” me๋‹ค.
console.log(me.getName()); // โ‘  Lee

Person.prototype.name = "Kim";

// getName ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฐ์ฒด๋Š” Person.prototype์ด๋‹ค.
console.log(Person.prototype.getName()); // โ‘ก Kim

22.2.3 ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ํ˜ธ์ถœ

  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์—๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฐ”์ธ๋”ฉ๋œ๋‹ค.
// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function Circle(radius) {
  // ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  this.radius = radius;
  this.getDiameter = function () {
    return 2 * this.radius;
  };
}

// ๋ฐ˜์ง€๋ฆ„์ด 5์ธ Circle ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
const circle1 = new Circle(5);
// ๋ฐ˜์ง€๋ฆ„์ด 10์ธ Circle ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ
const circle2 = new Circle(10);

console.log(circle1.getDiameter()); // 10
console.log(circle2.getDiameter()); // 20

๋ฉ”์„œ๋“œ ํ•จ์ˆ˜๋ž€?

  • ๋ฉ”์„œ๋“œ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋กœ ์ •์˜๋œ ํ•จ์ˆ˜๋กœ, ํ•ด๋‹น ๊ฐ์ฒด์˜ ์†์„ฑ์„ ์ฝ๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

    ๐Ÿ“Œ ํŠน์ง•

    • ๊ฐ์ฒด์˜ ์†์„ฑ๊ณผ ์—ฐ๊ด€๋œ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜
    • ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœ๋  ๋•Œ, this๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.
    • new ํ‚ค์›Œ๋“œ ์—†์ด ํ˜ธ์ถœ

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ž€?

  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋กœ, new ํ‚ค์›Œ๋“œ์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ํŠน์ง•

  • ์ƒˆ๋กœ์šด ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์šฉ๋„
  • new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœํ•  ๋•Œ, this๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ด.
  • ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ด๋ฆ„์€ ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ๊ด€๋ก€ (PascalCase)

22.2.4 Function.prototype.apply/call/bind ๋ฉ”์„œ๋“œ์— ์˜ํ•œ ๊ฐ„์ ‘ ํ˜ธ์ถœ

  • apply, call, bind ๋ฉ”์„œ๋“œ๋Š” Function.prototype.apply์˜ ๋ฉ”์„œ๋“œ๋กœ ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • apply, call ๋ฉ”์„œ๋“œ๋Š” this๋กœ ์‚ฌ์šฉํ•  ๊ฐ์ฒด์™€ ์ธ์ˆ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ ๋ฐ›์•„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
function getThisBinding() {
  return this;
}

// this๋กœ ์‚ฌ์šฉํ•  ๊ฐ์ฒด
const thisArg = { a: 1 };

console.log(getThisBinding()); // window

// getThisBinding ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ๊ฐ์ฒด๋ฅผ getThisBinding ํ•จ์ˆ˜์˜ this์— ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.
console.log(getThisBinding.apply(thisArg)); // {a: 1}
console.log(getThisBinding.call(thisArg)); // {a: 1}

๐Ÿ‘‰ ์œ„ ์˜ˆ์ œ์ฒ˜๋Ÿผ apply์™€ call์˜ ๋ณธ์งˆ์ ์ธ ๊ธฐ๋Šฅ == ํ•จ์ˆ˜ ํ˜ธ์ถœ apply์™€ call ๋ฉ”์„œ๋“œ๋Š” ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์— ์ธ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹๋งŒ ๋‹ค๋ฅผ ๋ฟ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

์ฐจ์ด์ :

  • apply๋Š” ์ธ์ˆ˜๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฌถ์–ด ์ „๋‹ฌํ•œ๋‹ค. call์€ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ ๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค.
function getThisBinding() {
  console.log(arguments);
  return this;
}

// this๋กœ ์‚ฌ์šฉํ•  ๊ฐ์ฒด
const thisArg = { a: 1 };

// getThisBinding ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ ๊ฐ์ฒด๋ฅผ getThisBinding ํ•จ์ˆ˜์˜ this์— ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.
// apply ๋ฉ”์„œ๋“œ๋Š” ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฌถ์–ด ์ „๋‹ฌํ•œ๋‹ค.
console.log(getThisBinding.apply(thisArg, [1, 2, 3]));
// Arguments(3) [1, 2, 3, callee: ฦ’, Symbol(Symbol.iterator): ฦ’]
// {a: 1}

// call ๋ฉ”์„œ๋“œ๋Š” ํ˜ธ์ถœํ•  ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋ฅผ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ ๋ฆฌ์ŠคํŠธ ํ˜•์‹์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค.
console.log(getThisBinding.call(thisArg, 1, 2, 3));
// Arguments(3) [1, 2, 3, callee: ฦ’, Symbol(Symbol.iterator): ฦ’]
// {a: 1}
  • apply์™€ call ๋ฉ”์„œ๋“œ์˜ ๋Œ€ํ‘œ์ ์ธ ์šฉ๋„๋Š” arguments์™€ ๊ฐ™์€ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์— ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ: arguments ๊ฐ์ฒด๋Š” ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋ฏ€๋กœ Array.prototype.slice์™€ ๊ฐ™์€ ๋ฐฐ์—ด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ ๋ชปํ•˜๋‚˜ apply, call ๋ฉ”์„œ๋“œ์—์„œ๋Š” ๊ฐ€๋Šฅํ•˜๋‹ค.

๐ŸŒŸ bind ๋ฉ”์„œ๋“œ๋Š” ๋ฉ”์„œ๋“œ์˜ this์™€ ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€์˜ ์ค‘์ฒฉ ํ•จ์ˆ˜ ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ this๊ฐ€ ๋ถˆ์ผ์น˜ํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

function getThisBinding() {
  return this;
}

// this๋กœ ์‚ฌ์šฉํ•  ๊ฐ์ฒด
const thisArg = { a: 1 };

// bind ๋ฉ”์„œ๋“œ๋Š” ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•œ thisArg๋กœ this ๋ฐ”์ธ๋”ฉ์ด ๊ต์ฒด๋œ
// getThisBinding ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑํ•ด ๋ฐ˜ํ™˜ํ•œ๋‹ค.
console.log(getThisBinding.bind(thisArg)); // getThisBinding
// bind ๋ฉ”์„œ๋“œ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋Š” ์•Š์œผ๋ฏ€๋กœ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
console.log(getThisBinding.bind(thisArg)()); // {a: 1}

โš ๏ธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ:

  • person.foo์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ด์ „(โ‘  ์‹œ์ )์— this๊ฐ€ person ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜. person.foo์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ ํ˜ธ์ถœ๋œ โ‘ก ์‹œ์ ์—์„œ this๋Š” ์ „์—ญ ๊ฐ์ฒด window๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
const person = {
  name: "Lee",
  foo(callback) {
    // โ‘  this => person
    setTimeout(callback, 100);
  },
};

person.foo(function () {
  console.log(`Hi! my name is ${this.name}.`); // โ‘ก Hi! my name is undefined.
  // ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this.name์€ ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ window.name๊ณผ ๊ฐ™๋‹ค.
  // ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ window.name์€ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋นŒํŠธ์ธ ํ”„๋กœํผํ‹ฐ์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์€ ''์ด๋‹ค.
  // Node.js ํ™˜๊ฒฝ์—์„œ this.name์€ undefined๋‹ค.
});

ํ•ด๊ฒฐํ•˜๋Š” ์ฝ”๋“œ:

  • person.foo์˜ ์ฝœ๋ฐฑํ•จ์ˆ˜๋Š” ์™ธ๋ถ€ ํ•จ์ˆ˜ person.foo์˜ ํ—ฌํผ ํ•จ์ˆ˜์˜ ์—ญํ• ์ด๋ฏ€๋กœ, this๊ฐ€ ์ƒ์ดํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.(์œ„ ์˜ˆ์ œ์ฒ˜๋Ÿผ) ๋”ฐ๋ผ์„œ, ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this๋ฅผ ์™ธ๋ถ€ ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this์™€ ์ผ์น˜์‹œ์ผœ์•ผํ•œ๋‹ค. => bind ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ
const person = {
  name: "Lee",
  foo(callback) {
    // bind ๋ฉ”์„œ๋“œ๋กœ callback ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ this ๋ฐ”์ธ๋”ฉ์„ ์ „๋‹ฌ
    setTimeout(callback.bind(this), 100);
  },
};

person.foo(function () {
  console.log(`Hi! my name is ${this.name}.`); // Hi! my name is Lee.
});