[JavaScript] OOP - 2. Objects

javascript

0. Table of Contents

  1. What is OOP
  2. Objects ๐Ÿ‘‰ Current Page
  3. Prototypes
  4. Prototypical Inheritance (TBD)
  5. ES6 Classes (TBD)
  6. ES6 Modules (TBD)

1. Creating Objects

const circle = {}; // using object literal syntax
  • ์ค‘๊ด„ํ˜ธ ({})๋ฅผ ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ๊ตฌ๋ฌธ์ด๋ผ๊ณ  ํ•œ๋‹ค.

const circle = {
  radius: 1,
  location: {
    x: 1,
    y: 1
  },
  draw: function() {
    console.log('draw');
  }
};
  • ๊ฐ์ฒด๋Š” key-value ์Œ์„ ๊ฐ€์ง„๋‹ค.
  • value ๊ฐ’์œผ๋กœ ๊ฐ์ฒด๋‚˜ ํ•จ์ˆ˜๋„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด์˜ ์†์„ฑ์œผ๋กœ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๋ฉ”์†Œ๋“œ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
  • ์œ„์˜ circle ๊ฐ์ฒด๋Š” Properties๋กœ radius์™€ location๊ฐ€ ์žˆ๊ณ  Methods๋กœ draw๊ฐ€ ์žˆ๋‹ค.

circle.draw(); // ์ถœ๋ ฅ ๊ฒฐ๊ณผ : draw
  • Dot (.)์œผ๋กœ ๊ฐ์ฒด์˜ Properties ๋ฐ Methods์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

2. Factories and Constructors

2-1. Factories

  • Bad Example

    const circle1 = {
      radius: 1,
      location: {
        x: 1,
        y: 1
      },
      draw: function() {
        console.log('draw');
      }
    };
    
    const circle2 = {
      radius: 2,
      location: {
        x: 2,
        y: 2
      },
      draw: function() {
        console.log('draw');
      }
    };
    • ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด ๋‚ด์˜ ๊ฐ draw ๋ฉ”์†Œ๋“œ๋Š” ๋™์ผํ•œ ์—ญํ• ์„ ํ•œ๋‹ค. ์ด ๋•Œ draw ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๋„ฃ๊ฒŒ ๋˜๋ฉด ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ ์ค‘๋ณต์ด ๋ฐœ์ƒํ•œ๋‹ค. factory๋‚˜ constructor function์„ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜์˜ Good Example์„ ๋ณด์ž.

  • Good Example - Using Factory

    // Factory Function
    function createCircle(radius, x, y) {
      return {
        radius,
        location: {
          x,
          y
        },
        draw: function() {
          console.log('draw');
        }
      };
    }
    
    const circle1 = createCircle(1, 1, 1);
    const circle2 = createCircle(2, 2, 2);
    • createCircle์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ–ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ์ฒด ๋‚ด์˜ ์†์„ฑ์€ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„์˜ค๋„๋ก ์ฒ˜๋ฆฌํ•œ๋‹ค.
    • ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ Factory Function ์„ ์ด์šฉํ•œ ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค.
    • Factory Function์„ ์ด์šฉํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ๋งค๋ฒˆ ๋‹ค์‹œ ์ •์˜ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

2-2. Constructors

// Constructor Function
function Circle(radius, x, y) {
  this.radius = radius;
  this.location = {
    x,
    y
  }
  this.draw = function() {
    console.log('draw');
  }
}

const myCircle = new Circle(1, 1, 1);
console.log(myCircle.radius); // 1
  • Constructor Function์˜ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์œผ๋กœ ์ฒซ ๊ธ€์ž๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ํ•œ๋‹ค.
  • Factory Function์ด Object๋ฅผ returnํ•˜๋Š” ๋ฐฉ์‹์ด์˜€๋‹ค๋ฉด, Constructor Function์€ this ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
  • Constructor Function์„ ์ด์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • new ํ‚ค์›Œ๋“œ๋Š” ๋นˆ ๊ฐ์ฒด({})๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜๊ณ  ํ•จ์ˆ˜ ๋‚ด this๋Š” ์ด ๋นˆ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋œ๋‹ค.
  • this๊ฐ€ ์ด ๋นˆ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์ด ๋นˆ ๊ฐ์ฒด์— this.radius ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ Properties์™€ Methods๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Constructor Function์ด ์ž๋™์œผ๋กœ return this๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ Properties์™€ Methods๊ฐ€ ์ถ”๊ฐ€๋œ ์ด ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ณ  ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด๋ฅผ myCircle์— ํ• ๋‹นํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— myCircle.radius ์„ ์ถœ๋ ฅํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ 1์ด ์ถœ๋ ฅ๋œ๋‹ค.
  • ๋งŒ์•ฝ new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  const badCircle = Circle(2, 2, 2);์™€ ๊ฐ™์ด ์ž‘์„ฑํ–ˆ๋‹ค๋ฉด ํ•จ์ˆ˜ ๋‚ด this๋Š” badCircle๊ฐ€ ์•„๋‹Œ Window(๋ธŒ๋ผ์šฐ์ € ๊ธฐ์ค€)๊ฐ€ ๋œ๋‹ค.
  • constructor ์†์„ฑ

    console.log(myCircle.constructor); // f Circle(...) {...}
    console.log(Circle.constructor); // f Object() {...}
    • ๋ชจ๋“  Object ๋Š” constructor ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ myCircle.constructor๋Š” Circle ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    • ๊ทธ๋ฆฌ๊ณ  Circle.constructor๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๋‚ด์žฅ๋œ ํ•จ์ˆ˜์ธ Object ํ•จ์ˆ˜์ด๋‹ค.

2-3. Functions are Objects

function Circle(radius, x, y) {
  this.radius = radius;
  this.location = {
    x,
    y
  }
  this.draw = function() {
    console.log('draw');
  }
}

const myCircle = new Circle(1, 1, 1);
  • ์œ„์˜ Circle ํ•จ์ˆ˜๋Š” ์‚ฌ์‹ค ํ•˜๋‚˜์˜ Object๋‹ค.
  • Circle. ์„ ์ž…๋ ฅํ•˜๋ฉด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉค๋ฒ„(methods, properties)๋“ค์ด ์ž๋™ ์ถ”์ฒœ ๋ชฉ๋ก์œผ๋กœ ๋œฌ๋‹ค. (ex. apply, arguments, bind, call, caller, length, name, prototype, toString, โ€ฆ) oop 2
  • JavaScript์˜ ๋ชจ๋“  ๊ฐ์ฒด๋Š” Constructor ์†์„ฑ์ด ์žˆ๊ณ  ์ด Constructor๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
  • ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด๋ผ๊ณ  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ Circle ํ•จ์ˆ˜๋„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด์ด๋ฏ€๋กœ Constructor ์†์„ฑ์„ ๊ฐ€์ง€๊ณ , ์ด Constructor๋Š” ์ด Circle์„ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ๋œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    ๋”ฐ๋ผ์„œ Circle.constructor ์„ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ฦ’ Function() { [native code] } (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์— ๋‚ด์žฅ๋œ Constructor์ธ function)๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.
  • function Circle() {...} ์™€ ๊ฐ™์ด ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ function constructor์„ ์ด์šฉํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค.

3. Primitives and Reference Types

3-1. ๋‘ ๊ฐ€์ง€์˜ ํƒ€์ž… ์ข…๋ฅ˜

  • JavaScript์—๋Š” ๋‘ ๊ฐ€์ง€ ํƒ€์ž… ์ข…๋ฅ˜๊ฐ€ ์กด์žฌํ•œ๋‹ค.

    1. Value Types (Primitives)

      • Number
      • String
      • Boolean
      • Symbol
      • undefined (ES6)
      • null (ES6)
    2. Reference Types

      • Object
      • Function
      • Array

3-2. Primitives์™€ Objects์˜ ๋™์ž‘ ๋ฐฉ์‹ ๋น„๊ต

  • Primitives์™€ Objects๋Š” ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฅธ๋ฐ, JavaScript์˜ Prototypes๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฐ˜๋“œ์‹œ ๊ผญ ์•Œ์•„์•ผ ํ•œ๋‹ค.

  • Primitives

    let x = 10;
    let y = x;
    
    x = 20;
    
    console.log(x); // 20
    console.log(y); // 10
    • ์œ„์˜ ์ฝ”๋“œ์—์„œ x์™€ y๋Š” ์™„์ „ํžˆ ๋…๋ฆฝ๋œ ๋‘ ๊ฐœ์˜ ๋ณ€์ˆ˜์ด๋‹ค.
    • ์ฒ˜์Œ x์— 10์„ ํ• ๋‹นํ•˜๊ณ  ๊ทธ ์ดํ›„์— y์— x๋ฅผ ํ• ๋‹นํ•œ ํ›„ x์— 20์œผ๋กœ ์žฌํ• ๋‹นํ•˜๋ฉด x๋Š” 20์œผ๋กœ ๋ณ€๊ฒฝ๋˜์ง€๋งŒ y๋Š” x์˜ ๋ณ€๊ฒฝ๊ณผ๋Š” ์ƒ๊ด€์—†์ด ์—ฌ์ „ํžˆ 10์ด๋‹ค.
    • ๊ฐ’์„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ๋•Œ ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ ๋ณ€์ˆ˜ ๋‚ด๋ถ€์— ํ•ด๋‹น ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

  • Objects

    let x = { value: 10 };
    let y = x;
    
    x.value = 20;
    
    console.log(x.value); // 20
    console.log(y.value); // 20
    • x.value์™€ y.value๋Š” ๋ชจ๋‘ 20์ด๋‹ค.
    • ๊ฐ์ฒด๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜์— ์ €์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ฐ์ฒด๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ณณ์— ์ €์žฅ๋˜๊ณ  ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜์˜ ์ฃผ์†Œ๋Š” ํ•ด๋‹น ๋ฉ”๋ชจ๋ฆฌ ๋ณ€์ˆ˜ ๋‚ด๋ถ€์— ์ €์žฅ๋œ๋‹ค.
    • let y = x; ์™€ ๊ฐ™์ด y์— x๋ฅผ ํ• ๋‹นํ•˜๊ฒŒ ๋˜๋ฉด ์ฐธ์กฐ ํ• ๋‹น์ด ์ผ์–ด๋‚œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด ์ž์ฒด๊ฐ€ ๋ณต์‚ฌ๋˜์–ด ์ƒˆ๋กœ์šด ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ์ฃผ์†Œ๊ฐ’์ด ๋ณต์‚ฌ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
    • ๋”ฐ๋ผ์„œ x์™€ y๋Š” ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋˜๊ณ  x.value์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด y.value์˜ ๊ฐ’๋„ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์ด๋‹ค. oop 2 1

  • ๊ฒฐ๋ก 

    • Primitives are copied by their value
    • Objects are copied by their reference

  • Primitives are copied by their value - Example

    let number = 10;
    
    function increase(number) { 
      number++;
    }
    
    increase(number);
    console.log(number); // 10;
    • increase ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ํ•จ์ˆ˜์—์„œ ๋ฐ›์€ number๋ผ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ฝ”๋“œ 1ํ–‰์˜ number์™€๋Š” ์™„์ „ํžˆ ๋ณ„๊ฐœ์˜ ๋ณ€์ˆ˜์ด๋‹ค.
    • ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ number์˜ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๋”๋ผ๋„ 1ํ–‰์˜ number์™€๋Š” ์ƒ๊ด€์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ๋งˆ์ง€๋ง‰ ํ–‰์—์„œ number๊ฐ’์„ ์ถœ๋ ฅํ•˜๋ฉด 10์ด ์ถœ๋ ฅ๋œ๋‹ค.

  • Objects are copied by their reference - Example

    let obj = { value: 10 };
    
    function increase(obj) { 
      obj.value++;
    }
    
    increase(obj);
    console.log(obj.value); // 11;
    • increase ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ํ•จ์ˆ˜์—์„œ ๋ฐ›์€ obj๋ผ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ฝ”๋“œ 1ํ–‰์˜ obj์™€๋Š” ๋ณ„๊ฐœ์˜ ๋ณ€์ˆ˜์ด์ง€๋งŒ ๊ฐ™์€ ๊ฐ์ฒด { value: 10 }์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. (๊ฐ์ฒด๋Š” ์ฐธ์กฐ ๋ณต์‚ฌ๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ.)
    • ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ obj.value์˜ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด 1ํ–‰์˜ obj๋„ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ๋งˆ์ง€๋ง‰ ํ–‰์—์„œ obj.value๋ฅผ ์ถœ๋ ฅํ•˜๋ฉด 11์ด ์ถœ๋ ฅ๋œ๋‹ค.

4. Working with Properties

4-1. Adding or Removing Properties

function Circle(radius) {
  this.radius = radius;
  this.draw = function() {
    console.log('draw');
  }
}

const circle = new Circle(10); // circle object ์ƒ์„ฑ

circle.location = { x: 1 }; // location ์†์„ฑ ์ถ”๊ฐ€
console.log(circle); // { radius: 10, location: { x: 1 }, draw: f }

circle['name'] = 'c1';
console.log(circle); // { radius: 10, location: { x: 1 }, name: 'c1', draw: f }

delete circle['location'];
delete circle.name;
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ์ฒด๋Š” ๋™์ (dynamic)์ด๋‹ค.
  • ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ํ›„์— ํ•ด๋‹น ๊ฐ์ฒด์— ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ณ  ๋˜ ์†์„ฑ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“  ์†์„ฑ์„ ๋ฏธ๋ฆฌ ์ •์˜ํ•˜์ง€ ์•Š์•„๋„ ํ•„์š”์— ๋”ฐ๋ผ ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง„ ์ดํ›„์— ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.
  • ๊ฐ์ฒด์˜ ์†์„ฑ์€ .์ด๋‚˜ [] ์œผ๋กœ ์ ‘๊ทผ/์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Dot Notation(.)์€ Brackets Notation([])๋ณด๋‹ค ํ‘œ๊ธฐ๋ฒ•์ด ์‹ฌํ”Œํ•˜๋‹ค.
  • Bracket([])์€ ๋™์ ์ธ ์†์„ฑ๋ช…์œผ๋กœ ์ ‘๊ทผํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค. ex) circle[propertyName]
  • ๋˜ํ•œ Bracket([])์€ ์œ ํšจํ•œ ์‹๋ณ„์ž๊ฐ€ ์•„๋‹Œ ์†์„ฑ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.

    • circle.center-location๊ณผ ๊ฐ™์€ ์ ‘๊ทผ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
    • circle['center-location']๊ณผ ๊ฐ™์€ ์ ‘๊ทผ์€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๊ฐ์ฒด์˜ ์†์„ฑ์„ ์ œ๊ฑฐํ•  ๋•Œ๋Š” delete Operator ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

4-2. Enumerating Properties

  1. for in loop

    function Circle(radius) {
      this.radius = radius;
      this.draw = function() {
        console.log('draw');
      }
    }
    
    const circle = new Circle(10);
    
    for (let key in circle) {
      console.log('key is ' + key);
      console.log('value is ' + circle[key]);
    }
    • ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋ฐ˜๋ณตํ•˜๊ฑฐ๋‚˜ ์—ด๊ฑฐํ•ด์•ผํ•  ๋•Œ for in loop๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ฐ์ฒด ๋‚ด ์†์„ฑ์˜ key ๋“ค์„ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋Œ๋ฉด์„œ ๊ฐ€์ ธ์˜จ๋‹ค.
    • ๊ฐ์ฒด ๋‚ด ์†์„ฑ์˜ value์— ์ ‘๊ทผํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” circle[key]์™€ ๊ฐ™์ด ์ ‘๊ทผํ•˜๋ฉด ๋œ๋‹ค.
  2. Object.keys()

    const keys = Object.keys(circle);
    console.log(keys); // ["radius", "draw"]
    • Object.keys()๋Š” ๊ฐ์ฒด ๋‚ด ๋ชจ๋“  key๊ฐ’๋“ค์„ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.
  3. in operator

    if ('radius' in circle) {
      console.log('Circle has a radius')
    }
    • in operator๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐ์ฒด๊ฐ€ ํŠน์ • key๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

5. Private Properties

5-1. Abstraction

function Circle(radius) {
  this.radius = radius;
  
  this.defaultLocation = {
    x: 0,
    y: 0,
  };

  this.computeOptimumLocation = function() {
    // ...
  }

  this.draw = function() {
    this.computeOptimumLocation();
    console.log('draw');
  }
}

const circle = new Circle(10);
circle.defalutLocation = false; // Bad
circle.computeOptimumLocation(); // Bad
  • object type์ธ circle.defaultLocation์— ๋œฌ๊ธˆ์—†์ด false๋ฅผ ํ• ๋‹นํ•œ๋‹ค๊ฑฐ๋‚˜,
    draw ๋ฉ”์†Œ๋“œ ์•ˆ์—์„œ๋งŒ ํ˜ธ์ถœ ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋Š” computeOptimumLocation ๋ฉ”์†Œ๋“œ๋ฅผ ์ง์ ‘์ ์œผ๋กœ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ์ฒด๋ฅผ ๋‚˜์œ ์ƒํƒœ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.
  • ์ด ๋•Œ ์šฐ๋ฆฌ๊ฐ€ ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฐœ๋…์ด Abstraction(์ถ”์ƒํ™”)๋ผ๋Š” ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ ๊ฐœ๋…์ด๋‹ค.
  • ์ถ”์ƒํ™”๋ž€, ์„ธ๋ถ€์‚ฌํ•ญ์„ ์ˆจ๊ธฐ๊ณ  ํ•„์ˆ˜์‚ฌํ•ญ๋งŒ ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (Hide the details, Show the essentials)
  • ์ถ”์ƒํ™”๋ฅผ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด DVD Player์ฒ˜๋Ÿผ ๋‚ด๋ถ€๋Š” ๋ณต์žกํ•œ ๋กœ์ง์„ ๊ฐ–๊ณ  ์žˆ์ง€๋งŒ ์™ธ๋ถ€์— ๋ณด์—ฌ์ง€๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•œ ๋ช‡ ๊ฐœ์˜ ๋ฒ„ํŠผ ๋ฟ์ด๋‹ค.
  • ์ถ”์ƒํ™”๋ฅผ ํ†ตํ•ด์„œ ์œ„์˜ Circle ํ•จ์ˆ˜์—์„œ radius์™€ draw๋งŒ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•˜๊ณ  defaultLocation๊ณผ computeOptimumLocation์€ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•ด๋ณด์ž.

5-2. Private Properties

function Circle(radius) {
  this.radius = radius;
  
  let defaultLocation = {
    x: 0,
    y: 0,
  };

  let computeOptimumLocation = function() {
    // ...
  }

  this.draw = function() {
    computeOptimumLocation();
    console.log('draw');
  }
}

const circle = new Circle(10);
  • ํ•จ์ˆ˜ ๋‚ด์— local ๋ณ€์ˆ˜๋ฅผ ๋‘๋ฉด ์ด ๋ณ€์ˆ˜๋Š” ๊ฐ์ฒด์˜ properties๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•จ์ˆ˜ ๋‚ด์˜ ๋กœ์ปฌ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜ ๋ฐ–์œผ๋กœ ๋น ์ ธ๋‚˜๊ฐ€๋Š” ์ˆœ๊ฐ„ ์Šค์ฝ”ํ”„๋ฅผ ๋ฒ—์–ด๋‚˜๊ฒŒ ๋˜๊ณ  ์ด ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ this.defaultLocation ๋Œ€์‹  let defaultLocation๊ณผ ๊ฐ™์ด ๋กœ์ปฌ ๋ณ€์ˆ˜๋กœ ์ •์˜ํ•˜๋ฉด ํ•จ์ˆ˜ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์ˆจ๊ธธ ์ˆ˜ ์žˆ๋‹ค.
  • ์šฐ๋ฆฌ๋Š” defaultLocation๊ณผ computeOptimumLocation์„ ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ์ปฌ ๋ณ€์ˆ˜๋กœ ๋ณ€๊ฒฝํ–ˆ๊ณ 
    draw ๋ฉ”์†Œ๋“œ ๋‚ด์—์„œ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์—ˆ๋˜ this.computeOptimumLocation() ๋Œ€์‹  computeOptimumLocation() ์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค.
  • draw ๋ฉ”์†Œ๋“œ ๋‚ด์—์„œ computeOptimumLocation์„ ํ˜ธ์ถœํ•˜๋ฉด Circle ์™ธ๋ถ€์—์„œ draw ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ computeOptimumLocation์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š”๋ฐ,
    ์ด๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํด๋กœ์ €(Closure) ๊ฐœ๋… ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•˜๋‹ค.

6. Getters and Setters

์œ„์—์„œ๋Š” ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•˜์ง€ ๋ชปํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ๋‘์—ˆ๋Š”๋ฐ
์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ˆ˜์ •์€ ๋ชปํ•˜๋„๋ก ํ•˜๊ณ  ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

6-1. ๋ฐฉ๋ฒ• 1 - ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค

function Circle(radius) {
  this.radius = radius;
  
  let defaultLocation = {
    x: 0,
    y: 0,
  };

  this.getDefaultLocation = function() {
    return defaultLocation;
  }

  this.draw = function() {
    console.log('draw');
  }
}

const circle = new Circle(10);
console.log(circle.getDefaultLocation()); // { x: 0, y: 0 }
  • defaultLocation์ด๋ผ๋Š” ๋ณ€์ˆ˜๋Š” Circle ํ•จ์ˆ˜ ์™ธ๋ถ€์—์„œ ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋งŒ
    getDefaultLocation์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ (ํด๋กœ์ € ๊ฐœ๋…์„ ์ด์šฉํ•ด) defaultLocation ๋ณ€์ˆ˜๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. (์ˆ˜์ •์€ ๋ถˆ๊ฐ€๋Šฅ)

6-2. ๋ฐฉ๋ฒ• 2 - defineProperty์˜ Getters

function Circle(radius) {
  this.radius = radius;
  
  let defaultLocation = {
    x: 0,
    y: 0,
  };

  this.draw = function() {
    console.log('draw');
  }

  Object.defineProperty(this, 'defaultLocation', {
    get: function() {
      return defaultLocation;
    }
  });
}

const circle = new Circle(10);
console.log(circle.defaultLocation); // { x: 0, y: 0 }
  • defineProperty๋ฅผ ์ด์šฉํ•ด์„œ ์†์„ฑ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • defineProperty์˜ ์ฒซ ๋ฒˆ์งธ argument๋กœ property์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๋Œ€์ƒ ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ค€๋‹ค. (this)
  • defineProperty์˜ ๋‘ ๋ฒˆ์งธ argument๋กœ property ์ด๋ฆ„์„ ๋„ฃ์–ด์ค€๋‹ค.
  • defineProperty์˜ ์„ธ ๋ฒˆ์งธ argument๋กœ๋Š” ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด์ค€๋‹ค. ์ด ๊ฐ์ฒด์— get ์ด๋ผ๋Š” ์ด๋ฆ„์˜ key๋ฅผ ์ง€์ •ํ•ด์ฃผ๊ณ  value๋กœ๋Š” ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.
    ์œ„ ์ฝ”๋“œ์˜ ๋งˆ์ง€๋ง‰ ์ค„์—์„œ circle.defaultLocation๊ณผ ๊ฐ™์ด ์ ‘๊ทผํ•˜๋ฉด ์ด get ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
  • circle ๊ฐ์ฒด๋ฅผ ์ถœ๋ ฅ ํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒˆ๋กœ์šด property์ธ defaultLocation์ด ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ read-only ์†์„ฑ์ด๋‹ค. ๋งŒ์•ฝ์— ์ด ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด setters๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. oop 2 2

6-3. ๊ฐ’์„ ์ˆ˜์ •ํ•  ๋•Œ๋Š” Setters๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

function Circle(radius) {
  this.radius = radius;
  
  let defaultLocation = {
    x: 0,
    y: 0,
  };

  this.draw = function() {
    console.log('draw');
  }

  Object.defineProperty(this, 'defaultLocation', {
    get: function() {
      return defaultLocation;
    },
    set: function(value) {
      if (!value.x || !value.y) {
        throw new Error('Invalid location.');
      }
      defaultLocation = value;
    }
  });
}

const circle = new Circle(10);
circle.defaultLocation = { x: 10, y: 20};
console.log(circle.defaultLocation); // { x: 10, y: 20 }

Reference



๐Ÿ‘‹@Jess2
๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ปFrontend Developer

GitHubFacebookLinkedIn