λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
🌌 | WEB DEV/Vanilla JS

JS_κΈ°λ³Έ 문법 (24)_ μƒμ„±μž ν•¨μˆ˜

by KASSID 2023. 3. 31.

λͺ©μ°¨

    728x90

    1. μƒμ„±μž ν•¨μˆ˜

    ν•¨μˆ˜λŠ” μž¬μ‚¬μš©κ°€λŠ₯ν•œ μ½”λ“œλ₯Ό λ¬ΆλŠ” 것 외에도 객체λ₯Ό μƒμ„±ν•˜λŠ” 역할을 μˆ˜ν–‰ν•  수 μžˆλ‹€.

    β€» function으둜 μ„ μ–Έλœ ν•¨μˆ˜λŠ” 기본적으둜 μƒμ„±μž ν•¨μˆ˜μ˜ κΈ°λŠ₯을 κ°–λŠ”λ‹€.

     

     

    μ˜ˆμ‹œ) 객체 생성

    const student1 = {
      name : 'Sam',
      idNum : 20,
      say () {
        return `μ•ˆλ…•ν•˜μ„Έμš”. ${idNum}번 ${name}μž…λ‹ˆλ‹€.`;
      }
    };
    
    const student2 = {
      name : 'Tom',
      idNum : 25,
      say () {
        return `μ•ˆλ…•ν•˜μ„Έμš”. ${idNum}번 ${name}μž…λ‹ˆλ‹€.`;
      }
    };

    μœ„μ™€ 같이 λΉ„μŠ·ν•œ ν˜•νƒœμ˜ 객체λ₯Ό μ—¬λŸ¬κ°œ λ§Œλ“€μ–΄μ•Όν•˜λŠ” 경우 같은 μ½”λ“œλ₯Ό λ°˜λ³΅ν•˜λŠ” 것이기 λ•Œλ¬Έμ—

    ν•¨μˆ˜λ₯Ό ν™œμš©ν•˜λ©΄ λ”μš± νŽΈλ¦¬ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

     

     

    μƒμ„±μž ν•¨μˆ˜ 생성 Rule

      - ν•¨μˆ˜λͺ…을 λŒ€λ¬Έμžλ‘œ μ •μ˜ν•œλ‹€.
      - return 문이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€. (객체λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λž‘ 닀름)
      - μƒμ„±μž ν•¨μˆ˜λ₯Ό new μ—°μ‚°μžμ™€ ν•¨κ»˜ μ‚¬μš©ν•œλ‹€. (newλ₯Ό μ‚¬μš©ν•΄μ•Ό μƒμ„±μž ν•¨μˆ˜μ˜ κΈ°λŠ₯을 μˆ˜ν–‰ν•¨, μ•ˆ 뢙이면 μΌλ°˜ν•¨μˆ˜)
      - ' this.~ ' λ‘œ 객체의 ν”„λ‘œνΌν‹°λ“€μ„ μ •μ˜ν•œλ‹€.
      - μƒμ„±μž ν•¨μˆ˜μ—μ„œλŠ” λ©”μ„œλ“œ μ •μ˜κ°€ λΆˆκ°€ν•˜λ‹€.

     

    μ˜ˆμ‹œ)

    function Student(name, idNum) {
      this.name = name;
      this.idNum = idNum;
      this.say = function() {
        return `μ•ˆλ…•ν•˜μ„Έμš”. ${idNum}번 ${name}μž…λ‹ˆλ‹€.`;
      }
    }

     

     

    const student1 = new Student('Sam', 20);
    const student2 = new Student('Tom', 25);

     

    이처럼 new μ—°μ‚°μžλ₯Ό λΆ™μ—¬μ„œ μ‚¬μš©ν•΄μ•Όλ§Œ μ˜λ„ν•œλŒ€λ‘œ 객체λ₯Ό 생성할 수 μžˆλ‹€.

     

    λ§Œμ•½ 이λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.

    // new μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ€ 경우
    const student3 = Student('David', 15);
    
    console.log(student3);
    
    >>> undefined

     


    2. μƒμ„±μž ν•¨μˆ˜λ‘œ λ§Œλ“€μ–΄μ§„ 객체

    μƒμ„±μž ν•¨μˆ˜λ‘œ λ§Œλ“€μ–΄μ§„ κ°μ²΄λŠ” λ‹€λ₯Έ λ°©μ‹μ˜ 객체와 λ‹€λ₯΄λ‹€.

     

    1) ν”„λ‘œν† νƒ€μž… prototype

    ν”„λ‘œν† νƒ€μž…μ€ JSμ—μ„œ 객체지ν–₯을 κ΅¬ν˜„ν•  수 μžˆλ„λ‘ λ•λŠ” 역할을 ν•œλ‹€.

    μ΄ˆκΈ°μ—λŠ” ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— ν”„λ‘œν† νƒ€μž…μœΌλ‘œ κ΅¬ν˜„μ„ ν•˜μ˜€λ‹€.

     

    ν΄λž˜μŠ€μ— λΉ„ν•΄ λ’€λ–¨μ–΄μ§€λŠ” 것이 μ•„λ‹Œ μ‚¬μš©μ— 따라 더 κ°•λ ₯ν•˜κ²Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

    λ˜ν•œ 클래슀 μžμ²΄κ°€ ν”„λ‘œν† νƒ€μž…μ„ 기반으둜 λ§Œλ“€μ–΄μ‘Œλ‹€!

     

    이에 λŒ€ν•œ μžμ„Έν•œ μ΄μ•ΌκΈ°λŠ” 좔후에 λ”°λ‘œ λ‹€λ£¨κΈ°λ‘œ ν•˜κ³  κ°„λ‹¨νžˆλ§Œ μ•Œμ•„λ³΄μž!

     

     

    μ˜ˆμ‹œ) μƒμ„±μž ν•¨μˆ˜μ™€ 객체 생성

    function Player(name, job){
      this.name = name;
      this.job = job;
      this.info = function () {
        return `μ†Œν™˜μ‚¬λͺ… : ${this.name} | 직업ꡰ : ${this.job}`;
      }
    }
    
    const player1 = new Player('Kassid', '전사');
    
    console.log(player1);
    
    >>> Player {name: 'Kassid', job: '전사', info: ƒ}

     

    μœ„μ˜ 객체에 ν”„λ‘œν† νƒ€μž…μ„ μ΄μš©ν•˜μ—¬ μƒˆλ‘œμš΄ ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•΄λ³΄μž!

    //.prototype을 μ΄μš©ν•˜μ—¬ μƒˆ ν”„λ‘œνΌν‹° μΆ”κ°€
    Player.prototype.attack = function() {
      return '곡격!';
    }

    기쑴에 미리 μƒμ„±ν•œ 객체에도 μƒˆλ‘œμš΄ ν”„λ‘œνΌν‹°κ°€ 생긴 것을 μ•Œμˆ˜ μžˆλ‹€.

    console.log(player1.attack());
    
    >>> 곡격!

     

    ν”„λ‘œν† νƒ€μž…μ„ μˆ˜μ •ν•˜λ©΄ μƒˆλ‘œ λ§Œλ“€μ–΄μ§ˆ μ˜ˆμ •μΈ 객체와 이미 μ‘΄μž¬ν•˜λŠ” 객체 λͺ¨λ‘ ν•΄λ‹Ή λ‚΄μš©μ΄ μ μš©λœλ‹€.

     

    λΉ„μœ ν•˜μžλ©΄ λ³Έμ‚¬μ—μ„œ λ°°ν¬ν•˜λŠ” 메뉴얼과 같은 κΈ°λŠ₯을 ν•œλ‹€.

     

    ν•˜μ§€λ§Œ μ—¬κΈ°μ„œ μ£Όμ˜ν•  점은 ν”„λ‘œν† νƒ€μž…μ„ μ΄μš©ν•΄ μΆ”κ°€ν•œ 것은

    일반 ν”„λ‘œνΌν‹°μ™€ λ‹€λ₯΄λ‹€λŠ” 것이닀. (μΈμŠ€ν„΄μŠ€ vs ν”„λ‘œν† νƒ€μž…)

    console.log(player1);
    
    >>> 
    Player {name: 'Kassid', job: '전사', info: ƒ}
        info: ƒ ()
        job: "전사"
        name: "Kassid"
        [[Prototype]]: Object
            attack: ƒ ()
            constructor: ƒ Player(name, job)
            [[Prototype]]: Object

    μœ„μ˜ μ˜ˆμ‹œμ—μ„œ μ•Œ 수 μžˆλ“― [Prototype] 내에 μ •μ˜κ°€ λ˜μ–΄ μžˆλ‹€.

     

    이에 λŒ€ν•œ λ‚΄μš©μ€ 좔후에 μžμ„Ένžˆ λ‹€λ£° μ˜ˆμ •μ΄λ‹€!

     

     

    2) λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ λ§Œλ“  κ°μ²΄λ“€κ³Όμ˜ 비ꡐ

    μœ„μ—μ„œ μ–ΈκΈ‰ν•œλŒ€λ‘œ μƒμ„±μžν•¨μˆ˜λ‘œ λ§Œλ“  κ°μ²΄λŠ” λ‹€λ₯Έ 것듀과 λ‹€λ₯΄λ‹€.

    그것을 직접 비ꡐ해보며 μ•Œμ•„λ³΄μž!

     

    // μƒμ„±μž ν•¨μˆ˜
    function Player(name, job){
      this.name = name;
      this.job = job;
      this.info = function () {
        return `μ†Œν™˜μ‚¬λͺ… : ${this.name} | 직업ꡰ : ${this.job}`;
      }
    }
    
    // 객체 λ°˜ν™˜ ν•¨μˆ˜
    function createPlayer(name, job){
      return {
        name, job,
        info (){
          return `μ†Œν™˜μ‚¬λͺ… : ${this.name} | 직업ꡰ : ${this.job}`;
        }
      }
    }

     

    3가지 λ°©λ²•μœΌλ‘œ λ§Œλ“  객체듀을 λΉ„κ΅ν•΄λ³΄μž.

    μƒμ„±μž ν•¨μˆ˜, 객체 λ°˜ν™˜  ν•¨μˆ˜, 객체 λ¦¬ν„°λŸ΄ 각각의 λ°©μ‹μœΌλ‘œ 생성해보면 μ•„λž˜μ™€ κ°™λ‹€.

    // 1. μƒμ„±μž ν•¨μˆ˜ 이용
    const player1 = new Player('Kassid', '전사');
    
    // 2. 객체 λ°˜ν™˜ ν•¨μˆ˜ 이용
    const player2 = createPlayer('Kassid', '전사');
    
    // 3. 객체 λ¦¬ν„°λŸ΄ 방식
    const player3 = {
      name : 'Kassid',
      job : '전사',
      introduce : function () {
        return `μ†Œν™˜μ‚¬λͺ… : ${this.name} | 직업ꡰ : ${this.job}`;
      }
    }

     

    console.log(player1);
    console.log(player2);
    console.log(player3);

    μœ„μ˜ κ²°κ³Ό 화면을 보면 μ•Œ 수 μžˆλ“―μ΄

    였직 μƒμ„±μžλ‘œ μƒμ„±ν•œ 객체만 닀름을 μ•Œ 수 μžˆλ‹€.

     

    μ΄λŠ” logμ—μ„œ ν‘œμ‹œν•˜λŠ” κΈ°λŠ₯이고

    객체 prototype의 constructorλ₯Ό μ‚΄νŽ΄λ³΄μ•„λ„ λ‹€λ₯Έ 것을 μ•Œ 수 μžˆλ‹€.

    μƒμ„±μž ν•¨μˆ˜λ‘œ λ§Œλ“  객체
    λ‹€λ₯Έ λ°©λ²•μœΌλ‘œ λ§Œλ“  객체

     

    이λ₯Ό ν†΅ν•΄μ„œ μƒμ„±μžλ‘œ μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€μž„μ„ 확인할 수 μžˆλ‹€. 

     

    λ˜ν•œ

    ' instanceof 'μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄λ„ ν•΄λ‹Ή 객체가 μƒμ„±μž ν•¨μˆ˜μ— μ˜ν•΄ λ§Œλ“€μ–΄μ‘ŒλŠ”μ§€λ₯Ό 확인할 수 μžˆλ‹€.

    console.log(player1 instanceof Player);
    console.log(player2 instanceof Player);
    console.log(player3 instanceof Player);
    
    >>> true
    >>> false
    >>> false

     

     

    3. μƒμ„±μž ν•¨μˆ˜ 자체의 ν•„λ“œμ™€ ν•¨μˆ˜

    // μƒμ„±μž ν•¨μˆ˜
    function Player(name, job){
      this.name = name;
      this.job = job;
      this.info = function () {
        return `μ†Œν™˜μ‚¬λͺ… : ${this.name} | 직업ꡰ : ${this.job}`;
      }
    }
    
    // μƒμ„±μž μžμ²΄μ— ν”„λ‘œνΌν‹° μΆ”κ°€
    Player.age = '23'
    Player.attack = function(){
      return '곡격!';
    }

     

    μœ„μ™€ 같이 μƒμ„±μž ν•¨μˆ˜ μžμ²΄μ— μƒˆλ‘œμš΄ ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•œλ‹€.

    μ΄λŸ¬ν•œ 방법을 μ‚¬μš©ν•œλ‹€λ©΄ μ–΄λ–€ 점이 λ‹€λ₯ΌκΉŒ?

     

     

    λ¨Όμ € μƒμ„±μž ν•¨μˆ˜ μžμ²΄μ—λ„ 점 μ—°μ‚°μžλ₯Ό μ΄μš©ν•˜μ—¬ μ ‘κ·Όν•  수 μžˆλ‹€.

    // μƒμ„±μž ν•¨μˆ˜ μžμ²΄μ— μ ‘κ·Όν•˜κΈ°
    console.log(Player.attack());
    
    >>> 곡격!

     

    μ΄λ²ˆμ—” μƒμ„±μž ν•¨μˆ˜μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œ ν›„ ν•΄λ‹Ή ν•¨μˆ˜μ— μ ‘κ·Όν•΄λ³΄μž.

    const player1 = new Player('Sally', 'ꢁ수');
    
    // 일반 ν”„λ‘œνΌν‹°μ™€ ν”„λ‘œν† ν† μž…μ—μ„œ μƒμ„±ν•œ ν•¨μˆ˜ 각각 μ ‘κ·Ό
    console.log(player1.info());
    console.log(player1.attack());
    
    >>> μ†Œν™˜μ‚¬λͺ… : Sally | 직업ꡰ : ꢁ수
    >>> Uncaught TypeError: player1.attack is not a function

    이처럼 기쑴의 일반 ν”„λ‘œνΌν‹° ν•¨μˆ˜μ—λŠ” 무리없이 접근이 κ°€λŠ₯ν•˜μ§€λ§Œ

    ν”„λ‘œν† νƒ€μž…μ„ μ΄μš©ν•˜μ—¬ μƒˆλ‘œ μΆ”κ°€ν•œ ν”„λ‘œνΌν‹°λŠ” 접근이 λΆˆκ°€ν•˜λ‹€.

     

    μ΄λŸ¬ν•œ 방식은 μƒμ„±ν•œ μΈμŠ€ν„΄μŠ€λ“€μ΄ μ•„λ‹Œ

    μƒμ„±μž ν•¨μˆ˜ μžμ²΄μ— ν•„μš”ν•œ κΈ°λŠ₯을 λ§Œλ“€λ•Œ 주둜 μ‚¬μš©λœλ‹€.

     

     

    4. new μ—°μ‚°μž μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것 λ°©μ§€ν•˜κΈ°!

    생성사 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  λ•Œ μœ„μ—μ„œ λ‹€λ€˜λ˜ κ²ƒμ²˜λŸΌ new μ—°μ‚°μžλ₯Ό κΌ­ μ΄μš©ν•΄μ•Όν•œλ‹€.

    λ§Œμ•½ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 경우 undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.

     

    ν•˜μ§€λ§Œ 이λ₯Ό κ°œλ°œμžκ°€ μ„€κ³„μ‹œμ— 방지할 수 μžˆλŠ” 방법이 μžˆλ‹€.

    λ°”λ‘œ new.target을 μ΄μš©ν•˜λŠ” 것이닀!

     

    new.taget은 μƒμ„±μž ν•¨μˆ˜λ‘œ λ§Œλ“€μ–΄μ§„ 객체인 κ²½μš°μ— 항상 ν•¨κ»˜ μƒμ„±λœλ‹€.

    λ”°λΌμ„œ μ΄κ²ƒμ˜ 유무λ₯Ό 확인 ν›„

    없을 경우 new μ—°μ‚°μžλ₯Ό 뢙인 μƒμ„±μž ν•¨μˆ˜λ₯Ό μž¬κ·€ν˜ΈμΆœν•˜λ©΄ λœλ‹€.

     

    μ˜ˆμ‹œ)

    // μƒμ„±μž ν•¨μˆ˜
    function Player(name, job){
      this.name = name;
      this.job = job;
      this.info = function () {
        return `μ†Œν™˜μ‚¬λͺ… : ${this.name} | 직업ꡰ : ${this.job}`;
      }
      
      if (!new.target){
        return new Player(name, job);
      }
    }
    
    const p1 = new Player('Kassid', '전사');
    const p2 = Player('Kassid', '전사');

    μœ„μ˜ μ˜ˆμ‹œμ—μ„œ p1은 μƒμ„±μž ν•¨μˆ˜λ₯Ό newμ—°μ‚°μžμ™€ ν•¨κ»˜ μ΄μš©ν•˜μ˜€κ³  

    p2λŠ” 그렇지 μ•Šμ€ 잘λͺ»λœ μ˜ˆμ‹œμ΄λ‹€.

     

    이λ₯Ό ν™•μΈν•΄λ³΄μž!

    console.log(p1);
    console.log(p2);
    
    >>> Player {name: 'Kassid', job: '전사', info: ƒ}
    >>> Player {name: 'Kassid', job: '전사', info: ƒ}

    잘λͺ» μ‚¬μš©ν•œ p2 μ—­μ‹œ undefinedκ°€ μ•„λ‹Œ μƒμ„±μž ν•¨μˆ˜λ‘œ λ§Œλ“  객체가 μ •μƒμ μœΌλ‘œ λ“€μ–΄κ°„ λͺ¨μŠ΅μ΄λ‹€.

     

    λŒ“κΈ€