[JS] 전개구문, 구조분해할당, 클래스

오리·2024년 4월 2일
post-thumbnail

드디어 Js프로젝트가 끝나고 진도를 나가게 되었다.
오늘부터 배우는 건 조금 다른 방식으로 정리해보려 한다!
전체적인 개념은 간단히 하고, 실습위주로 하는 것이 더 효율적일 것 같다는 판단하에.. (물론 막 결정한건 아니고~ 리더님이 조언해주심) 최대한 개념은 짧게 내가 외우기 좋도록 적어보겠다!

1. 전개구문 (Spread)

  • 반복 가능한 것들에 사용한다. 요소들에게 접근하여 한개씩 분리한다.
    즉, 기존에는 for, map, for (let) of, forEach로 사용했던 것을 간단하게 하는 것이다!

1) 배열 요소 한개씩 뽑아내기

<기존 방식>

const lunchMenu = ["국밥", "치킨마요", "돈가스", "파스타"];
const dinnerMenu = ["라면", "볶음밥", "바질페스토파스타", "냉동볶음밥"];
**for 문**
for (let i = 0; i < lunchMenu.length; i++) {
	cosole.log(lunchMenu[i]);
}

**forEach**
lunchMeun.forEach(menu) => {
	cosole.log(menu);
}
for let of
for ( let menu of lunchMenu ) {
	cosole.log(menu);
}
**map**
lunchMenu.map {
	cosole.log(menu);
}

이렇게 다양한 방식으로 객체의 각 요소에 접근할 수 있다. 그러나 더 간단하게 할 수있다! 전개구문을 사용하면 된다.

<전개구문>

cosole.log(...lunchMenu);

객체명 앞에 점 세개만 붙여주면 완성된다.
전개구문은 ...[1,2,3,4]와 같이 바로 배열객체 작성한 뒤, 접근 가능하다.

2) 배열 합치기

런치메뉴와 디너메뉴의 배열을 그대로 합치려면 어떻게 하면 좋을까?

<기존 방식>

  • 전개구문 없이 map과 push를 사용한다.
newArr = [];

function addMenu () {
	lunchMenu.map((menu) => newArr.push(menu));
    dinnerMenu.map((menu) => newArr.push(menu));
}
addMenu();

-> 의문🤔 : 그런데 같은 menu라는 이름을 사용해도 되는걸까? 중복되지는 않을까?? 라는 생각이 들었다.

서로 별개의 콜백함수 내의 변수라서 상관없단다! 그리고 둘의 이름은 같지만 담긴 값은 서로 별개로 담겨있다고 한다 ! 해결~!

아무튼, 기존에는 저렇게 조금 복잡한 방법으로 했다면, 이제는 전개구문을 사용하면 아주 간단해진다!

<전개구문>

cosole.log([...lunchMenu, ...dinnerMenu]);

한줄로 끝내버린다... 굿! 헷갈리면 안되는게 전개구문은 하나씩 뽑아주는 애라서 꼭 배열안에 담아야 우리가 원하는모양이 나오게 된다.

다른방법들도 있다.

< concat() >

  • 두개를 연결해주는 메서드이다. 착각하면 안된다. 위처럼 뽑아내는 메서드가 아니다!
let arr = lunchMenu.concat(dinnerMenu);
cosole.log(arr)

3) 문자열

  • 문자열도 한글자씩 분리시킬 수 있다.

<전개구문>

let str = fighting!!
cosole.log(...str);


위와 같이 분리된다. 이를 배열에 담으려면

let strArr = [...str];
cosole.log(strArr);

< split >

  • 인자로 받은 것을 기준으로 나눈 뒤, 배열을 반환한다.
let strArr2 = str.split("");
cosole.log(strArr2);

4) 객체

  • 전개구문은 객체에도 각 요소에 접근하고, 합칠 수도 있다.
    단! 객체 내부의 함수는 점접근법으로만 접근 가능하다.
let me1 = {
  name: "layla",
  height: 173,
  married: false,
  pet: null,
};

let me2 = {
  ko_name: "레일라",
  like: ["baking", "traveling"],
  pet: {
    name: "janghwa",
    like: ["layla", "sleeping"],
  },
  
  greeting: function () {
    console.log(
      `안녕하세요 제 이름은 ${this.name}이고, 키는 ${this.height}cm 입니다.`
    );
  },
};

let me = {...me1, ...me2}
// 합칠때, 동일한 객체가 있으면 뒤 객체를 기준으로 합쳐진다.
cosole.log(me);

  • 단, 함수에 접근할 때는 점접근법을 사용한다.
me.greeting();
  • 합치면서 동시에 새로운 키를 추가할 수도 있다.
let me = {
...me1,
...me2,
mbti : "istp",
};

2. 구조 분해 할당

  • 말그대로 분해시킨 다음에 할당시키는 것을 의미한다. 기존에는 배열의 인덱스의 값에 직접 접근하여 변수에 할당했다면 이제는 바로 변수에 할당할것이다.

1) 배열

< 구조 분해 할당>

const icecream = ["민트초코", "엔쵸", "스크류바"];

const [mintchoco, screwbar, ancho] = icecream;
cosole.log(mintchoco); // "민트초코"
cosole.log(screwbar); // ! "엔쵸" 출력
  • 위에서 알수 있다 싶이 구조 분해 할당은 순서가 중요하다!

  • 중간에 사용하지 않는 요소가 있을 때, 생략하고 할당한다.

const [mincho, , screw] = icecream;
// cosole.log(ancho); -> 할당되지 않았으므로 출력되지 않는다.
  • 가장 마지막 요소를 변수에 저장하지 않을때는 쉼표없이 그냥 생략해도 된다.
const [mincho, ancho] = icecream;
  • 구조분해하는 배열보다 변수가 많을 때 배열의 길이를 넘어가는 변수는 자동으로 undefined
const [mincho, ancho, screw, yogert] = icecream;
cosole.log(yogert); // undefined
  • default값을 미리 선언할수도 있다. 단, 기존 값이 존재하지 않을때 default값이 사용된다.
const [mincho, ancho, screw = "screw default", yogert = "yogert default"] = icecream;
cosole.log(screw); // "스크류바"
cosole.log(yogert); // yogert default 사용됨

값 교환

<기존>

let value1 = "second";
let value2 = "first";

let temp;

temp = value1; // second를 temp에게
value1 = value2; // first를 value1에게
value2 = temp; // second를 value1에게

<구조 분해 할당>

const [value1, value2] = [value2, value1]
  • 한줄로 줄일 수 있다!

2) 객체

  • 배열 구조 분해 할당과는 다르게, 순서는 상관 없고 객체의 key의 이름이 일치해야 변수에 값이 저장되어 할당할 수 있다.
const myPhone = {
  name: "아이폰",
  color: "white",
  version: 13,
};
const { color, name, version } = myPhone;
console.log(name, color, version); 

// 다른 이름으로 변수 할당 불가
const {c,n,v} = myPhone;
cosole.log(c,n,v); // undefined undefined undefine
  • 만약 다른이름으로 변수 할당하려면 다음과 같이 해야한다.
const {name : nn, color: cc, version : vv } = myPhone;
  • default 값도 지정할 수 있다.
const { name, color, version, giga = 256 } = myPhone;
  • 전개구문과 같이 사용할수도 있다.
const {key1, key2, ...obj} = {
key1 : "value1",
key2 : "value2",
key3 : 2,
key4 : "value4",
};
cosole.log(key1, key2);
cosole.log(obj); // 할당 안된 나머지가 모두 저장됨.

3. 클래스

  • 공통된 것의 특징을 담은 클래스를 만들고, 그에 파생되는 부가적인 오브젝트들을 만들 수 있다. 즉, 오브젝트들의 공통점을 담아놓은 곳이 클래스다.
  • 속성과 메소드의 집합으로 작성된 설계도와 같다.
class House {
  // constructor : 생성자 함수
  // House라는 클래스의 속성을 초기화
  constructor(name, age, window) {
    this.name = name; // 이 클래스엔 name이라는 key를 가질 것이고, value는 생성자 함수에서 전달받은 name이다.
    this.age = age;
    this.window = window;
  }
  // 메서드
  consoleInfo() {
    console.log(
      `이 아파트의 이름은 ${this.name}이고, ${this.age}년 건축되었습니다.`
    );
  }
  consoleWindow() {
    console.log(`${this.name}아파트의 창문은 ${this.window}개 입니다.`);
  }
}
  • 이 클래스를 이용해 오브젝트를 만들 수 있다.
// House 클래스를 사용해 오브젝트 만들기
const house1 = new House("고덕 그라시움", 2020, 10);
const house2 = new House("고덕 아르테온", 2010, 7);
const house3 = new House("리앤파크", 2019, 11);
const house4 = new House("고래힐", 2015, 5);
console.log(house1); // 오브젝트 출력
house1.consoleInfo(); // house1의 객체 값을 이용해 메소드 실행

1) 상속 (extends)

  • 기존에 있던 클래스의 속성과 메소드를 받아와서 추가로 더 작성할 수 있다.
  • 기존 메소드를 재정의하는 것을 오버라이딩이라 한다.
  • super()는 부모에게 작성된 것을 받아오는 것이다.
class Apartment extends House {
constructor(name, age, window, floor, password) {
 super(name, age, window);
	this.floor = floor; // Aprtment 클래스에서 사용할 속성
    this.password = password;
  }
   consolePassword() {
    console.log(`이 아파트의 비밀번호는 ${this.password} 입니		다.`);
  }
  // 오버라이딩
    consoleWindow() {
    console.log(
      `이 아파트의 창문은 모두 ${this.window}개 이고, 총 ${
        this.floor
      }층이므로 모든 창문의 갯수는 ${this.window * this.floor}개 		입니다.`
    );
  }
}
const apt1 = new Apartment("Ipark", 2017, 6, 20, 12345);
apt1.consoleWindow(); // 새롭게 정의된 메서드 사용
apt1.consolePassword(); // 새로운 메서드 추가 가능
apt1.consoleInfo(); // 부모 메서드 그대로 사용 가능

2) 인스턴스 (instance)

  • 클래스를 기반으로 생성된 객체이다. 즉, 인스턴스는 클래스의 구체적인 실현체라고 볼 수 있다.
  • 예를들어 Shape라는 클래스가 있을때, let rec = new Shape(3,4); 이라는 코드를 작성하면 여기서 rec가 인스턴스이다.
profile
암튼 해보는 개발자호소인

0개의 댓글