[Day 15] dataset & pass by reference

thru·2023년 6월 22일
0

FEDC-TIL

목록 보기
14/21

pass by reference in 중고거래

오늘 공부한 내용 🌧️

오늘은 fetch API를 이용해 간단한 상점 페이지를 구현하는 강의를 들었다.
그리고 과제를 구현하면서 궁금했던 사항이 있어 적어보려고 한다.


새로 알게된 내용 🌱

dataset 속성

이전 강의에도 흘러가듯이 나왔던 것 같은데 기록을 안하니 머리에 안남은 것 같아서 정리해보려고 한다.

HTML5 에서 새로 도입된 속성으로 HTML 요소에 커스텀 속성을 표시하는 표준화된 방법을 제시한다.
어떤 요소던 간에 data-로 시작하는 속성을 붙이면 사용할 수 있다.

<div id="example" data-index="7" data-creator="thru" >요론 느낌으로</div>

자바스크립트에서는 DOM 생성 시점에 해당 속성들을 dataset 맵에 하나로 모아서 관리한다.
접근할 때는 기존처럼 getAttribute를 사용할 수도 있지만, 객체의 속성을 읽는 것처럼 $element.dataset.name과 같은 형식으로 접근할 수 있다.
이 때 name은 data-뒤에 붙은 이름을 사용하는데 대시-가 있는 경우 자동으로 camelCase로 변환된다.
읽을 수만 있는 건 아니고 새로 값을 넣어주는 것도 가능하다.

HTML 요소에 붙어있는 속성이므로 CSS에서도 속성 선택자 등으로 접근이 가능하다.

#example[data-index='7'] {
	display: flex;
}

접근 보조 기술이 접근할 수 없기 때문에 접근 가능해야 하는 내용은 데이터셋 속성으로 표시하면 안된다.
마찬가지로 검색 크롤러도 인덱싱하지 않으므로 관련 컨텐츠 표시용으로 사용하는 건 부적합하다.

그렇다고 아예 노출되면 안되는 값을 넣는 용도로 쓰면 안되는데 개발자 도구로는 보이기 때문이다.


Element.closest()

매개변수로 받은 CSS 선택자에 일치하는 요소를 찾을 때 까지 자신을 포함해서 조상 요소를 순회하는 메서드이다.
필요한 부모 노드를 찾을 때 parentNode 같은 걸로 반복문을 돌리지 않아도 된다는 장점이 있다.

기본 메서드를 잘 알고있으면 유용하게 쓸 수 있을 것 같다.


리마인드된 내용 🔨

pass by reference 의 맹점

과제하는 중에 parameter의 동작 관련해서 이해되지 않았던 사항이 있었다.
자바스크립트의 변수 할당 방식을 곰곰히 생각해보다가 해결되서 정리해보려고 한다.

먼저 문제가 되었던 코드는 대략 다음과 같다.

function TodoList() {
  this.state = [1, 2, 3];
  this.setState = (nextState) => {
    this.state = nextState;
  }
}

function TodoCount({todoState}) {
  this.print = () => {
  	console.log(todoState);
  }
}

const todoList = new TodoList();
const todoCount = new TodoCount({
  todoState: todoList.State,
});

todoList.setState([4, 5, 6]);

todoCount.print(); // [1, 2, 3] 이 출력된다.

todoCount의 매개변수로 todoList.State의 값을 가진 todoState라는 배열을 전달하고 내부에서 사용한다.

내가 착각한 것은 todoStatetodoList.state의 주소값이 전달된 것이므로 todoList에서 setStatestate를 변화시키더라도 todoCount 내부에서 변화된 state값에 접근이 가능할거라는 점이다.

핵심은 setState에서 state자체를 변경시켰다는 것이다.
state의 내부 요소를 변경했다면 todoCount가 접근 가능한 게 맞지만 자체를 바꿔버리면서 state가 새로운 주소를 가리키게 됐고, todoCounttodoStatetodoList.state는 서로 다른 주소를 가리키는 상태가 된다.
결과적으로 todoCount에서는 todoList.state의 초기값만 볼 수 있다.

내가 해결한 방식은 함수를 전달하는 것이다.

function TodoCount({getTodoState}) {
  this.print = () => {
    console.log(getTodoState());
  }
}

const todoCount = new TodoCount({
  getTodoState: () => todoList.state,
}

이렇게 하면 print를 실행한 시점의 todoList.state를 가져오므로 문제를 해결할 수 있다.

pass by reference는 사실상 동기화라는 관념으로 고민없이 사용했던 건데 immutable update를 지향하는 프론트엔드 특성상 고심해서 사용해야겠다.


느낀점 🎬

위 과제관련 내용은 사실 과제할 때는 마음이 급해서 이유를 안찾아보고 바로 엎어버린 뒤 다른 방법으로 구현했다. 그런데 TIL 작성하면서 이걸 고민해보면 좋겠다는 생각에 파본건데 내 고정관념을 고치는 기회가 된 것 같다.


참조


profile
프론트 공부 중

0개의 댓글