TIL | DOM

unihit·2020년 12월 24일
0

TIL

목록 보기
5/25
post-thumbnail

DOM (Document Object Model)

DOM이란 웹페이지의 HTML을 계층화시켜 트리구조로 만든 객체 모델이다.
JavaScript는 이 model로 웹 페이지에 접근하고, 페이지를 수정할 수 있다.
DOM은 HTML인 웹 페이지와 스크립팅언어(JavaScript)를 서로 잇는 역할이다.

그래서 JavaScript는 document라는 전역객체를 통해 접근할 수 있다.
JavaScript의 document 객체는 DOM 구조를 접근하는 관문이며, document 객체는 HTML 문서를 나타낸다 말할 수 있다.

왜 HTML을 접근해야 하는가?

document 객체는 DOM트리의 root node에 접근하게 해준다.
document 객체로 요소(element)에 접근하듯이 요소의 속성(attribute)에도 접근할 수 있다.
그렇게 class, id도 추가하고 style도 수정할 수 있다.
요소의 내용(content)는 innerHTML으로 접근하고 수정할 수 있다.

document.body.innerHTML = '내용 다 바꿈';

위는 body 태그 내부에 있는 것을 '내용 다 바꿈'이라는 텍스트로 바꾼 것이다.
body 태그 내에 엄청나게 많은 요소가 있더라도 innerHTML을 사용하면 내용이 전부 교체된다.
특정 element를 접근하고 싶을 때는 어떻게 해야 할까?
tag, class, id와 같은 css selector로 접근 가능하다.

let blueElement = document.querySelector('.blue');
blueElement.style.backgroundColor = 'blue';

위와 같은 스타일도 수정할 수 있는데 css에서 사용했던 property 명과는 조금 달라보인다.
background-color 대신 backgroundColor로 접근한 것에 집중하자.
JavaScript에서 style 수정할 때 hypen(-)은 사용할 수 없다.
객체(Object)에서 프로퍼티 이름에 hypen(-)을 사용할 수 없던 이유와 같다.
그러므로 style의 프로퍼티에 접근하고 싶을 때 camelCase로 비꾸면 된다.
물론 element를 생성할 수도 있다.
createElement(tagName) 함수를 사용하면 요소(element)를 만들 수 있다.
위의 함수는 요소를 만들기만 할 뿐, 아직 HTML의 어디에 들어가야 할 지 지정해준 것이 아니다.
만든 후에는 어딘가의 element에 append 시켜줘야 한다.
innerHTML은 내용을 전부 대체 시켰다면 appendChild 함수는 요소의 뒤쪽에 붙여준다.

Object

객체의 키를 변수로 접근하기

객체의 키를 사용하는 여러 방법을 배웠는데 이 방법을 사용하면 객체의 특정 키의 값을 가져오는 것도 가능하지만, 반대로 객체에 특정 키를 만들고 값을 할당하는 것도 가능하다.
information 이라는 객체 하나를 만들어 예를 들어보자.

const information = {
  name: '김개발'
}

여기에 키 하나를 생성하고, 그 키에 값을 할당해 주려고 한다. 그런데 키와 값을 변수를 통해 받아 온다면 어떻게 해야 할까?

const verb = 'developes'
const project = 'facebook'

verb의 값을 키로 사용해야 하고, porject의 값을 그 키의 값으로 사용한다고 했을때

information[verb] = project // [A]
information.developes = 'facebook' // [B]

A와 같이 할당이 가능하다.
B의 방식으로도 할당이 가능할 수도 있겠지만, 이 경우 키와 값은 항상 정해져 있게 된다.
하지만 A와 같은 방법은 변수 verb와 project가 가지는 값에 따라 다른 키와 값을 가지는게 가능해진다.
즉, 하드코딩이 아닌 동적으로 값을 할당 할 수 있다는 것이다.

객체 순회하기

객체는 순서가 없고 키를 통해서만 접근해야 한다.
하지만 여러가지 이유로 객체에 있는 모든 키에 한번씩 접근해야 하는 코드를 써야 한다면 어떻게 해야 할까?
다행히도 객체도 배열처럼 순회가 가능하다.
다만 배열과 다르게 명확하게 정해진 순서가 없기 때문에, 어떤 순서에 따라 객체의 키에 접근하게 될지 알 수는 없다.
때문에 객체의 순회는 순서가 보장되지 않은 순회라고 부른다.
배열을 순회할때 다음과 같은 for 문을 사용했다.

const arr = ['coconut', 'banana', 'pepper', 'coriander']
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i])
}

이런 반복문은 배열이 length라는 키를 가지고 있고, 인덱스를 통해서 각 배열요소에 접근할 수 있었기 때문이다.
객체는 length 키가 따로 주어져있지 않고, 인덱스도 없기 때문에 이런식의 반복문은 불가능하다.
대신 크게 두 가지의 방법으로 객체의 반복문 작성이 가능하다.

1. Object.keys()

Object.keys 메소드는 어떤 객체가 가지고 있는 키들의 목록을 배열로 리턴하는 메소드다.
객체의 내장 메소드가 아니라 객체 생성자인 Object가 직접 가지고 있는 메소드다.

const obj = {
  name: 'melon',
  weight: 4350,
  price: 16500,
  isFresh: true
}

Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']

Object.keys 메소드가 리턴하는 값은 배열이기 때문에 이걸로 반복문을 사용할 수 있다.

const keys = Object.keys(obj) // ['name', 'weight', 'price', 'isFresh']

for (let i = 0; i < keys.length; i++) {
  const key = keys[i] // 각각의 키
  const value = obj[key] // 각각의 키에 해당하는 각각의 값

  console.log(value)
}

새로운 ES6 문법에서는 Object.keys 외에도 마찬가지로 Object 생성자의 메소드인 Object.values, Object.entries와 같은 자매품들이 추가되었다.
Object.values는 객체의 키가 아닌 값으로 이루어진 배열을 리턴한다.
Object.entries는 객체의 키와 값의 쌍으로 이루어진 길이 2짜리 배열로 이루어진, 배열을 리턴한다.

const values = Object.values(obj)
// values === ['melon', 4350, 16500, true]

const entries = Object.entries(obj)

/*
entries === [
  ['name', 'melon'],
  ['weight', 4350],
  ['price', 16500],
  ['isFresh', true]
]
*/

Object.entries가 조금 복잡해보이긴 하지만, Object.keys, Object.values, Object.entries 세가지 중에서 제일 유용하게 쓰인다.

2. for-in

객체를 순회하는 두번째 방법은 for-in 문이다.
반복문인 for문과 같은 종류의 문법이지만, 객체와 배열을 위해 특별히 존재하는, ES6에서 추가된 문법이다.
이건 객체의 순회 외에도, 일반적인 배열을 순회할 때도 매우 유용하게 쓰인다.

const arr = ['coconut', 'banana', 'pepper', 'coriander']

for (let i = 0; i < arr.length; i ++) {
  console.log(i)
  console.log(arr[i])
} 

앞서 예시로 등장했던 배열의 반복문이다.
이걸 간단하게 축약한 문법이 바로 다음과 같다.

for (let i in arr) {
  console.log(i)
  console.log(arr[i])
}

i를 0으로 초기화하고, 배열의 길이와 비교하고, i를 1씩 증가시키는 등의 코드를 생략할 수 있게 만든 ES6 문법이다.
이 for-in 문은 인덱스의 값으로 무엇을 할당하고, 반복문이 몇번 돌아야 할 지를 자바스크립트 엔진 내부에서 자동으로 결정하게 된다.
for-in 문은 배열뿐 아니라 객체에서도 작동하도록 만들어졌다.

const obj = {
  name: 'melon',
  weight: 4350,
  price: 16500,
  isFresh: true
}

for (let key in obj) {
  const value = obj[key]

  console.log(key)
  console.log(value)
}

이렇게 객체를 가지고 for-in 문을 사용하면, for-in 문의 인덱스에 해당하는 변수가, 숫자가 아닌 객체의 각각의 키에 해당하는 문자열을 할당받게 된다.

0개의 댓글