데브코스 13일차 ( 24.10.30 수 ) JavaScript

워니·2024년 10월 31일
0

Programmers Front-end

목록 보기
13/27

[Section 02] JavaScript 심화


< 11. 고급 함수 >

1. 즉시 호출 함수(IIFE)

  • 전역 범위를 오염 시키지 않고 싶을 때 사용
  • 실행된 함수를 다시 부를 수 없음, 호출과 동시에 아예 삭제됨
  • 실무에서 사용할 일은 거의 없다
(function greet() {
  console.log("Hello");
})(); // 소괄호로 묶어서 데이터처럼 취급하게 하고 호출
  • 익명 함수도 가능
(function () {
  console.log("Hello2");
})();
  • 화살표 함수도 가능
(() => {
  console.log("Hello3");
})();
  • 매개변수 사용도 가능
(function greet(name) {
  console.log("Hello, " + name);
})("매개변수");

const myModule = (function () {
  let privateVariable = "I am private";
  return {
    getPrivateValue() {
      return privateVariable;
    },
  };
})(); // myModule.getPrivateValue()치면, 콘솔창에 I am private 출력

2. 생성자 함수

  • 객체를 만들어 내는 함수
  • 항상 이름을 파스칼 케이스로 작성하는 관례가 있음
  • 생성자 함수로 객체를 생성하는 법
  • new 키워드를 붙이는 순간 생성자 함수의 역할을 함
< 객체 리터럴로 객체를 생성하는 방법 >
const userObj = {
  name: "철수",
  age: 30,
};
console.log(userObj);

< 생성자 함수로 객체를 생성하는 방법 >
function User() {
  this.name = "철수";
  this.age = 30;
  // const name = "철수";
  // const age = 30;
} // const는 잘 사용하지 않는다
const u = new User(); // new를 사용하면 this의 범위를 함수 안으로 정해준다
console.log(u.name);
  • 예시
    ex)
    function Car() {
      this.name = "benz";
      this.color = "white";
    }
    const car1 = new Car(); // 생성자 함수에 담긴 변수 car1을 인스턴스라고 함
    console.log(car1.name);  // benz
    console.log(car1.color);  // white

2.1. 생성자 함수 특징

  • 매개변수를 전달 받을 수 있음 (여러 개 작성 가능)
  • 객체의 속성은 동일하지만 값은 다른 객체를 만들어낼 때 편리함
function Car2(name, color) {
  this.name = name;
  this.color = color;
}
const car2 = new Car2("benz", "white");
console.log(car2.name); // benz
console.log(car2.color); // white

const car3 = new Car2("bmw", "black");
console.log(car3.name); // bmw
console.log(car3.color); // black
  • 매서드 사용도 가능
function Car3(name, color) {
  this.name = name;
  this.color = color;
  this.getInfo = function () {  // getInfo라는 매서드를 사용
    return `${this.name}, ${this.color}`;
  };
}
const car4 = new Car3("benz", "white");
console.log(car4.getInfo()); // benz, white
  • 멤버 속성이 없어도 작성 가능
function Calculator() {} // 멤버 속성이 직접적으로 작성되어 있진 않음
Calculator.prototype.add = function (a, b) {
  return a + b;
};
Calculator.prototype.subtract = function (a, b) {
  return a - b;
};
const instance = new Calculator();
console.log(instance.add(10, 2));  // 12
console.log(instance.subtract(10, 2));  8

2.2. 인스턴스

  • 일정한 모양의 객체를 만들지만 객체의 값은 다르게 만들어 준다
  • new 키워드는 함수를 호출해서 함수 내용을 객체로 만들어 주는 역할
function Car2(name, color) {
  this.name = name;
  this.color = color;
}
const car2 = new Car2("benz", "white");
console.log(car2.name); // benz
console.log(car2.color); // white

const car3 = new Car2("bmw", "black");
console.log(car3.name); // bmw
console.log(car3.color); // black 
// car2와 car3이 인스턴스
// Car2라는 일정한 모양의 함수를 만들지만 각각의 객체 값은 다르게 함
// new를 사용하면 생성자 함수의 속성을 인스턴스에 그대로 다 보냄
  • instanceof
    • 해당 객체가 인스턴스인지 확인하는 방법
    function Person() {}
    const person = new Person();
    
    console.log(person instanceof Person);
    // instanceof : 왼쪽에 있는 객체가 오른쪽 함수의 인스턴스인지 확인하는 방법
    // true 출력
    console.dir(Person.prototype instanceof Object);
    // Person 함수의 프로토타입도 어떤 것의 인스턴스임을 확인할 수 있음
    // true 출력

2.3. 고급 패턴

2.3.1. 생성자 함수를 프라이빗 하게 사용하는 방법

  • 외부에서 조작 못하게 한다면 프로토타입 사용 못 함
  • 예시
    • < 외부 조작이 불가능한 생성자 함수 >
      function Counter() {
        let count = 0;
        this.increment = function () {
          count++;
        };
        this.decrement = function () {
          count--;
        };
        this.getCount = function () {
          return count;
        };
      }
      const counter = new Counter();
      counter.increment(); // 1
      counter.increment(); // 2
      counter.increment(); // 3
      counter.decrement(); // 2
      counter.count = 100; // 100 , 외부에서 조작 불가능
      console.log(counter.getCount()); // 2
    • < 프로토타입을 사용한 생성자 함수에 외부 조작 가능 >
      function BankAccount(initialBalance) {
        // 생성자 함수는 항상 대문자로 시작
        this.balance = initialBalance;
      }
      BankAccount.prototype.deposit = function (amount) {
        this.balance += amount;
      };
      BankAccount.prototype.withdraw = function (amount) {
        this.balance -= amount;
      };
      const woori = new BankAccount(1000); // 초기 금액 1000원
      woori.deposit(2000); // 2000원 저축
      woori.balance = 10000000; // 외부 조작 1000만원
      console.log(woori.balance); // 1000만원 출력
    • < 생성자 함수를 외부 조작이 불가능하게 바꾼 것 >
      function BankAccount(initialBalance) {
        let balance = initialBalance;
        this.deposit = function (amount) {
          balance += amount;
        };
        this.withdraw = function (amount) {
          balance -= amount;
        };
        this.getBanlance = function () {
          return balance;
        };
      }
      const woori = new BankAccount(1000); // 초기 금액 1000원
      woori.deposit(2000); // 2000원 저축
      woori.balance = 10000000; // 외부 조작 불가
      console.log(woori.getBanlance()); // 3000원 출력

2.3.2. 생성자 함수 팩토리 패턴

function createPerson(type, name) {
  function Employee(name) {
    this.name = name;
    this.type = "employee";
  }

  function Manager(name) {
    this.name = name;
    this.type = "manager";
  }

  switch (type) {
    case "employee":
      return new Employee(name);
    case " manager":
      return new Manager(name);
  }
}
// 이렇게 함수 안에 함수들을 집어 넣어서 여러 개 사용 가능

2.3.3. 상속

  • 프로토타입 안에 프로토타입을 집어 넣어버리는 것

< 12. 프로토타입 >

  • 함수와 1 대 1로 매칭되는 프라이빗한 공간(객체)
  • 함수는 무조건 프로토타입 객체를 가지고 있다
  • 프로토타입 객체는 constructor__proto__를 무조건 가짐
  • constructor는 자신을 생성한 생성자 함수를 가리키고,
    __proto__는 자신의 상위 프로토타입을 가리킨다.
  • 공통된 속성을 프로토타입에 넣어두면서 메모리 사용을 줄일 수 있게 됨
  • 값을 수정할 일이 없는 속성을 프로토타입에 넣어서 사용함
  • 인스턴스만 __proto__를 가지고 있고, 프로토타입도 __proto__를 가지므로
    프로토타입 또한 어떤 것의 인스턴스이다.
  • 예시
    • < 동일한 매서드가 불필요하게 계속 해서 반복되는 예시 >

      function Car5(name, color) {
        this.name = name;
        this.color = color;
        this.getInfo = function () {
          return `${this.name}, ${this.color}`;
        };
      }
      const car5 = new Car5("benz", "white"); // 객체 car1 1개가 메모리 차지
      console.dir(car5);
      
      const car6 = new Car5("bmw", "black"); // 객체 car2 1개가 메모리 차지
      console.dir(car6);
      // 객체가 몇 번 찍어지든 getInfo 속성은 변하지 않고 있다
      // getInfo를 찍어내기 위해 불필요한 메모리가 계속 사용되고 있다
    • < 프로토타입을 이용하여 불필요한 반복을 없앤 예시 >

      function Car6(name, color) {
        this.name = name;
        this.color = color;
      }
      Car6.prototype.getInfo = function () {
        return `${this.name}, ${this.color}`;
      };
      const car7 = new Car6("benz", "white");
      console.dir(car7); // getInfo가 삭제됨
      
      const car8 = new Car6("bmw", "black");
      console.dir(car8); // getInfo가 삭제됨, color와 name만 나옴
      console.dir(car8.name); // bmw
      console.dir(car8.color); // black
      console.dir(car8.getInfo()); // bmw, black (왜 나오는걸까??)
      // 이해를 위해선 프로토타입 체인이라는 개념이 필요
    • < 매서드가 아닌 일반 속성 값도 프로토타입에 넣을 수 있음 >

      function Car7(name, color) {
        this.name = name;
        this.color = color;
      }
      Car7.prototype.type = "vehicle";
      const car9 = new Car7("bmw", "black");
      console.dir(car9.type); // vehicle

1. 프로토타입 체이닝

  • 인스턴스에서 생성자 함수의 프로토타입에 접근할 수 있는 방법
  • 인스턴스가 프로토타입 객체를 탐색해 나가는 과정
  • 모든 인스턴스는 숨겨져 있는 히든 속성인 프로토타입 참조 속성이 내장
  • __proto__ : 상위 프로토타입에 접근할 수 있음 (기본적으로 생략 가능)

2. 래퍼 객체

  • 자료형과 관련 있는 생성자 함수로부터 인스턴스 객체를 만드는 것
  • 자바스크립트 엔진이 기본 자료형의 값을 객체처럼 사용하기 위해서
    암묵적으로 만드는 객체
  • 해당 자료형과 관련 있는 생성자 함수의 인스턴스 개체로 감싼다
자료형이 숫자다?
그럼 임시로 만든 Number() 생성자 함수로부터 인스턴스 객체를 만들어 감싼다.

const userObj2 = {
  name: "철수",
  age: 20,
};
console.log(userObj2.hasOwnProperty("name"));

const PI = 3.14159265358979323846;
console.dir(PI);
// 3.141592653589793 그냥 숫자만 나열됨
console.log(PI.toFixed(2));
// 3.14
// toFixed 소수점 자리 자를 때, 2 = 소수점 2자리까지

const PI2 = new Number(3.14159265358979323846);
console.dir(PI2);
// [Number: 3.141592653589793]
console.log(PI2.toFixed(2));
// 3.14

< 하루 정리 >

오늘도 설명을 듣다가 막히는 부분이 있어서 멘탈이 흔들릴 뻔 했지만,
겨우 집중해서 따라 잡을 수 있었다.

어제 잠을 제대로 못 잔 탓인지 아침부터 못 일어나고 정신을 못차렸는데
카누 4봉지의 힘은 꽤 대단했다.

강사님 설명을 들을 때는 개념이 추상적인 부분이 있어서 
이해하기가 어려울 때도 있었지만, 
생성자 함수 문제 자체가 어렵게 낼 수 없는 것이라는 강사님의 말씀과 함께
반복해서 문제 풀이를 보고 또 보니 이해가 점점 되기 시작했다.

몇 분 뒤면 팀 미팅 발표를 하게 되는데 준비가 너무 미약해서 죄송스럽고
떨린다... 팀에서 제일 못하다 보니 발표 준비조차도 너무 어렵다...
팀원들과 비교돼서 더 더욱 ㅠㅠ

일단 오늘 발표 마무리 잘 하고 옵시다!
profile
첫 시작!

0개의 댓글