코드스테이츠/코드스테이츠 @ 개발 복습

[코드 스테이츠] 21일차, "3주차 복습 (2)" // DOM 다시 볼 것

Je-chan 2021. 8. 8. 21:52


[ 오늘의 TODO ]

  1. 코드 스테이츠) 목~금 내용 복습
    // spread, rest, 구조 분해 할당  
    // DOM
  2. 패스트 캠퍼스) 인강 3개 이상 듣기 // optional
  3. 생활) 물 1L 이상 마시기
  4. 생활) 수-토-일 운동 

 


[ 오늘의 복습 ]

1. Spread, Rest, 구조 분해 할당

  1-1) Spread

  주로 배열을 풀어 인자로 전달하거나, 각각의 요소로 넣기 위해 사용된다. 배열, 객체, 함수 인자 등에서 사용된다.

function makeString(x, y, z) {
  return x + y + z
}

const strings = ["Hello", " ", "Codestates"]

console.log( makeString(...strings)) // Hello Codestates

  미리 혼선을 방지하기 위해서 언급하지만, 현재 ... 은 함수의 매개변수로 들어간 것이 아니라 인자로 들어갔다. 이것을 강조하는 이유는 rest는 함수의 매개변수에 들어가기 때문이다. 

 

  이제 다른 예제들을 보면서 확실하게 개념을 정립하도록 하자.

let kixxVolleyball = ["안혜진", "오지영"]

let koreaVolleyball = ["김연경", "박정아", ...kixxVolleyball, "양효진"]

console.log(koreaVolleyball) 
  //  ["김연경", "박정아", "안혜진", "오지영", "양효진"]


koreaVolleyballNew = [...koreaVolleyball]
  // 배열을 복사한다기 보단 배열의 요소들을 다 가져와서 새 배열에 넣어주는 것
  // 서로 다른 배열이므로 서로가 서로에게 영향을 끼칠 수 없다.
koreaVolleyballNew.push( "김희진", "김수지", "염혜선") 

console.log(koreaVolleyball) 
  // ["김연경", "박정아", "안혜진", "오지영", "양효진"]
  
console.log(koreaVolleyballNew)
  // ["김연경", "박정아", "안혜진", "오지영", "양효진", "김희진", "김수지", "염혜선"]

 

 

  이번에는 객체에도 한 번 적용을 해볼 건데 배열과는 달리 객체에서는 주의해야할 점을 확인해보도록 한다.

 

let koreaVolleyball = {
  capatain: "김연경",
  setter: "염혜선",
  center: "김수지"
}

let koreaVolleyballNew = {
  setter: "안혜진",
  opposite: "김희진",
  Libero: "오지영"
}

let koreaVolleyballMerge = {
  ...koreaVolleyball, ...koreaVolleyballNew
}

console.log(koreaVolleyballMerge)
/*
  {
  capatain: "김연경", 
  setter: "안혜진", 
  center: "김수지", 
  opposite: "김희진", 
  Libero: "오지영"
  }
*/

 

  배열과 달리 객체에는 key값과 value가 존재한다, 만일 객체 두개를 가져오는 상황에서 같은 key가 존재한다면 순서상 나중에 spread된 객체의 value를 가져오게 된다.

 

  1-2) rest

  rest는 미리 언급했듯이 파라미터를 배열의 형태로 받아서 사용하는 것이다. sprad와 마찬가지로 ... 을 사용한다. 다시 한 번 말하지만 인자에 적는 것은 배열의 각 요소들을 하나 하나씩 spread하는 것이 spread, 파라미터를 배열의 형태로 받아서 사용하는 것이 rest다. 배열로 받아왔을 때의 장점은, 받아올 파라미터의 개수가 가변적일 때 좋고, 두 번째로는 배열의 메소드를 사용해서 파라미터들에게 변형을 쉽게 줄 수 있다는 점에서 장점이 있다. 만약, 인자들을 모두 더해주는 함수가 있다고 가정했을 때 일반적인 경우와 rest 문법을 사용했을 때의 경우를 비교해보자.

function sum (x, y, z) {
  return x + y + z  
} 

console.log(sum(1, 2, 3)) // 6
console.log(sum(1, 2, 3, 4)) // 6

function sumRest (...args) {
  return args.reduce((acc, curr) => {
    return acc + curr
  })
} 

console.log(sumRest(1, 2, 3)) // 6
console.log(sumRest(1, 2, 3, 4)) // 10
console.log(sumRest(1, 2, 3, 4, 5, 6)) // 21

   위에서 볼 수 있듯이 만약 일반적인 경우 매개 변수의 개수는 한정적이게 되므로 매개 변수 개수 이상의 인자를 받으면 무시하게 된다. 하지만, rest의 경우 모든 것을 다 배열로 가져와서 담고 있기 때문에 인자의 개수가 어떻게 변하더라도 원하는 결과를 나오게할 수 있으며 배열의 메소드를 활용할 수 있다.

 

  1-3) 구조 분해 할당

  구조 분해 할당은 말 그대로 분해하고 나서 새 변수에 할당해주는 것을 의미한다. 단, 이렇게 해줄 때는 선언 키워드(let, const)를 꼭 사용해줘야 하며 말그대로 할당이므로 변수에 쓰일 수 있는 타입을 사용해줘야 한다. 또 객체를 할당해줄 경우 객체의 key값으로 선언해줘야 한다. 만약 객체 그대로에 있는 key가 아닌 다른 값을 주고 싶다고 한다면     원래의key: 바꾸고싶은key   이렇게 해서 바꿔준다. 

 

const [a, b, ...rest] = ["김연경", "안혜진", "김희진", "이소영", "표승주", "정지윤", "박은진"]

console.log(a) // 김연경
console.log(b) // 안혜진
console.log(rest) // 김희진 이소영 표승주 정지윤 박은진

const {c: x, d, ...obj} = {c: "이소영", d: "표승주", e:"정지윤", f:"박은진"}
console.log(x) // 이소영
console.log(c) // c is not defined 에러
console.log(d) // 표승주
console.log(obj) // {e: "정지윤", f: "박은진"}

 

  함수에서도 구조 분해가 가능하다.

 

function cheer({nickname: bread, realName: {firstName: name}}){
  console.log(`${bread}, ${name} 파이팅!`);
}

let user = {
  age: 34,
  nickname: "식빵언니",
  realName: {
      firstName: "연경",
      lastName: "김"
  }
};

cheer(user) // 식빵언니, 연경 파이팅!

// 현재 파라미터 안에서 구조 분해 할당이 이뤄진 것
// {nickname: bread, realName: {firstName: name}} = user
// 여기서 realName은 조금 헷갈리는데 분석해보면 파라미터로 가져오는 것은 realName이 아니다
// user 내부 realName 내부 firstName을 가져오는 거고 그것을 변수 name으로 쓰겠다는 의미다.

 

2.  DOM

  2-1) DOM 이란?

  DOM은 Document Object Model로 HTML 요소를 객체처럼 조작할 수 있는 것을 뜻한다.

  이 때 조작하는 언어는 자바 스크립트 이외에 여러 언어들이 있을 수 있다.

  DOM은 트리구조로 돼있다. 

 

  2-2) JavaScript로 조작하기

    2-2-1) document.createElement('태그이름') 

  태그를 생성해주는 메소드다.  

 

    2-2-2) document.원하는엘리먼트.append(변수) / .appendChild(변수)

  자바 스크립트로 DOM의 요소 중 하나를 변수에 할당해주었다면 그 변수에 담긴 엘리먼트를 내가 원하는 노드 자리에 추가해주고 싶을 때 사용하는 메소드다. appendChild는 한 노드를 내가 원하는 노드의 자식에 추가해주고 싶을 때 사용하며 맨 마지막 자식으로 추가해준다. 

  

    2-2-3) querySelector, querlySelectorAll

  인자로 태그, id, class 이름 등을 받으며 querySelector는 인자로 받은 것이 가장 첫 번째로 오는 것만 가져온다. 예를 들어서 document.body.querySelector('.myDiv') 라고 한다면, Document 내부 body 엘리먼트 안에서 클래스 이름이 myDiv인 가장 첫 번째 엘리먼트를 가져오는 것이다. querySelectorAll은 모든 것을 배열의 형태(정확히 집자면 유사 배열로 Array-like Object 라고 한다)로 가져오는 것으로 아까 전의 예시에서 querySelector를 querySelectorAll 로 바꾼다면 Document 내부 body 엘리먼트 안에서 클래스 이름이 myDiv인 것 모두를 유사 배열의 요소로 집어 넣고 그것을 반환하는 것이다

 

    2-2-4) textContent

  태그 사이에 내용을 넣는 역할을 한다

 

    2-2-5) classList.add('클래스이름')  / classList.remove('클래스이름')

  이걸 사용하면 classList 앞에 적어준 엘리먼트에 인자로 넣은 클래스 이름을 추가하고(add) 제거한다(remove)

 

    2-2-6) 변수.remove( ) / .removeChild (child)

  append가 변수에 할당된 엘리먼트를 원하는 엘리먼트 자리에다 추가해주는 것이라면 remove는 변수라 선언된 엘리먼트를 제거하는 것이다. removeChild는 그 노드의 child를 제거하고 그 값을 리턴해준다. 그래서 만일, 모든 자식 노드들을 다 없애주고 싶다면 다음과 같이 한다.

 

while (section1.firstChild) {
	section1.removeChild(section1.firstChild)
}

// section1의 firstChild가 없을 때까지 계속해서 지워준다

 

  만약 내가 특정 클래스 이름을 가진 엘리먼트만을 지우고 싶다면 다음과 같이 하면 된다.

const wantDelete = document.querySelctorAll('.wantDelete')

for (let delete in wnatDelete) {
  wantDelete.remove()
}

 

  

 

  DOM에 대한 지식은 처음 공부하는 것이다 보니 아직 생소하다. 다음에 다시 와서 업데이트를 하도록 하자.