전체 글 118

프로토타입 더 알아보기

🙋‍♂️프로토타입이 뭐죠? 두 가지를 잘 구분해야 합니다. 내부슬롯으로서 프로토타입, [[Prototype]] 프로토타입 내부슬롯은 자바스크립트 엔진에서 관리하는 객체로, 자신(인스턴스)을 생성한 생성자 함수의 prototype 프로퍼티를 가리킨다. 금단의 프로퍼티, 던더프로토(__proto__)로 **[[Prototype]]**에 접근할 수 있다. 생성자 함수의 프로퍼티인 prototype 프로토타입(prototype)은 생성자 함수가 될 수 있는 모든 함수의 프로퍼티로 생기는 객체인데, 그 이름이 prototype이다. 지금은 잘 이해되지 않더라도 계속 읽고 실습해보면서 둘의 차이와 관계를 알아보아요! 🙋‍♂️더 자세히 말해주세요! ECMAScript를 참고해볼까요? 프로토타입은 "다른 객체들을 위한..

클래스 리스트 순서에 따른 구현은 위험하다!

HTML 엘리먼트에 접근할 때 클래스 이름으로 접근하고는 한다. 그리고 클래스 이름을 아예 데이터로 저장하기도 했다. 그리고 심지어 나는 클래스 리스트를 복제해 그 리스트의 요소를 pop하며 사용했는데 이는 안 좋은 행동인 것이 확실하다. 결론부터 말하자면, HTML에 작성된 클래스 순서가 영원히 보장되지 않고, 배포 주체에 따라 바뀔 수 있다. 예를 들어 보자. 아래와 같은 옵션이 있다. 옵션은 플레이 옵션(혼자, 대결)과 보드 크기(작은, 큰) 두 종류이며 각 옵션들 중 한 개씩 선택할 수 있다. // index.html 혼자 하기 대결하기 작은 게임 보드 큰 게임 보드 나는 아래와 같이 선택한 옵션 엘리먼트의 클래스 리스트를 받은 다음 pop하여 optionType과 optionName에 할당했다...

Javascript를 배우기에 알면 좋을 배경 지식들 1 (ECMAScript, 자바스크립트 엔진, 런타임)

이 글은 이 링크의 글을 기반으로, 저에게 필요한 내용을 군데군데 보충하여 작성되었습니다. ECMAScript는 Javascript랑 무슨 관계예요? ECMA International에 의해 제정된 표준들 중 하나인, ECMA-262가 ECMAScript를 정의합니다. ECMA International은 정보 통신에 대한 표준을 제정하는 비영리 표준화 기구입니다. ECMA-262는 ECMA International이 제정한 수많은 표준들 중 하나입니다. 따라서, ECMAScript는 ECMA International에 의해 제정된 ECMA-262 기술 규격에 의해 정의된 범용 스크립트 언어의 사양(specification)를 뜻합니다. 스크립트 언어는 무엇인가요? 존재하는 시스템 또는 실체(entity)..

조건문에 변수를 넣을 때 주의하자

오늘은 이런 트러블슈팅을 했다. 퀴즈 프로그램을 만드는 중, 기존에 만들어둔 버튼을 재활용하기 위해 버튼에 부착된 이벤트리스너를 제거해야 했다(이벤트 위임을 하면 아예 발생하지 않았을 문제 같기도 하다). 따라서 문제의 정답과 보기가 이미 존재할 때, 그 문제의 보기(선택지)를 초기화해주는 작업을 위한 코드, 즉 조건문을 작성했다. if (this.$validChoices && this.$correctAnswer) { this.#detachEventListenerFromChoices(); } 그런데 코드를 테스트 하는 도중, 정답을 클릭하지 않았는데 다음 문제로 넘어가거나, 정답을 눌렀을 때, 오답 표시도 함께 생기는 버그가 생겼다. 원인을 찾다가 이윽고 문제를 발견했다. $correctAnswer는 0..

읽고 있는, 읽어야 할 책을 간단히 정리하고 설명해보기

모던 자바스크립트 Deep Dive (완독) 와 함께 자바스크립트 참고서 역할로 가지고 있는 책. 굵기와 구체적이고 친절한 내용 덕분에 보고만 있어도 마음이 든든하다. 하지만 읽지 않으면 소용없으니까, 자바스크립트를 공부하는 중 모르는 내용이나 더 탐구할 내용이 있으면 인터넷만 찔끔 찾다가 넘어가지 말고, 이 책을 기본으로 나만의 방식으로 정리하는 습관을 들이자. 오브젝트 ( 1/5 완료) 객체 지향을 실습하고 배우기에 안성맞춤인 책이기 때문에 구매했다! 이것도 굵기가 상당해 묵직함 만큼 마음이 든든하다. 그런데 읽지 않으면 꿔다놓은 보릿자루, 그림의 떡, 낫 놓고 기역자 ... 객체지향 패러다임은 프로그래밍에 있어서 아주 중요한 개념이니 능숙해지기 위해 꼭 읽어야 하니, 그 소중함을 놓치지 말자. 하루..

리뷰/책 2021.03.15

배열을 같은 값으로 초기화할 때 하드코딩보다 Array(number).fill(something)를 사용하자.

오늘의 쬐그마한 배움이었다. this.#squares = [null, null, null, null, null, null, null, null, null] 어떤 배열을 하나의 값으로 초기화해야 한다면, 위와 같이 일일이 하드코딩하여 써주는 것 보다, 아래와 같이 `Array(number).fill(something)`를 상수(constant)와 함께 사용하는 것이 더 가독성과 이후 변경, 확장, 유지, 보수에 용이하다. const SQUARE_LENGTH = 9; const DEFAULT_SQUARE_CONTENT = null; this.#squares = Array(SQUARE_LENGTH).fill(DEFAULT_SQUARE_CONTENT); 참고 developer.mozilla.org/ko/docs..

Array 메소드(filter, find 등)의 반환 값을 잘 알아두자.

오늘은 이런 일이 있었다. 결론부터 말하자면, Array.filter 메소드의 반환 값이 배열이란 것을 몰라서 일어난 경험이다. 상황은 다음과 같은 함수에서 일어났다. export default class ScoreManager { /* ... */ score(player) { console.log(player) this.#playerScore[player.getType()] += 1; const $score = Array.from(this.$scores).find(($score) => $score.id === player.getType()); $score.textContent = this.getScore(player); } /* ... */ } 어떤 문제인지, 아래 score(player) 메소드에서 ..

자바스크립트 클래스 메소드에서 이벤트리스너 콜백 함수를 작성할 때 주의해야 할 this 바인딩

자바스크립트 클래스 안에서 이벤트리스너를 등록하고, 그 콜백 함수 안에서 this를 사용하려면 주의해야 한다. 아래는 board 엘리먼트의 자식 엘리먼트를 모두 선택해 각각에 이벤트리스너를 등록하는 메서드를 구현한 것이다. export default class BoardHandler{ #gameManager; /* ... */ #CLASS_NAME_BOARD_CHILD= ".board__child"; $allChildren = document.querySelectorAll(this.#CLASS_NAME_BOARD_CHILD); #initializeBoardElement() { this.$allChildren.forEach(($child) => ($child.textContent = "")); this.$..

초간단 팁: javascript parcel로 빌드할 때 class property, private mehtods 사용하는 방법

Parcel을 사용하게 되었는데 (지금까지 경험한 바로) 엄청 간단하고 편하다. 그저 parcel index.html이라는 간단한 명령어로, HTML, CSS, 거기에 링크된 자바스크립트 파일들 빠른 속도로 빌드하고 내장 개발용 서버까지 제공해준다. Parcel은 CommonJS와 ES6 파일 임포트를 모두 지원한다고 한다. 하지만 이 상태로는 현재 실험적 기능(experimental feature)인 Class fields는 자동으로 빌드되지 못한다. 따라서 에러가 발생한다. Javascript Class fields를 parcel을 통해 사용하고 싶다면, 역시 중간에 어떤 조치를 취해야 하는데 그것이 그 유명한 babel이다. 하지만 매우 간단하다. @babel/plugin-proposal-class..

고차함수를 활용한 이벤트리스너 부착과 제거

아래 코드는 캘린더의 날짜를 출력함과 동시에 이벤트리스너를 붙이고 (다음 달로 넘어갈 때, 다시 이벤트리스너를) 제거하고, 새로운 날짜에 대한 이벤트리스너를 붙이는 기능을 구현한 것의 일부이다. export default class CalendarController { /* ... */ #dateOfCalendarClickEventListenerRepository = {}; /* ... 다른 메서드들 ... */ #printDates() { for (/* 캘린더 날짜 하나씩 순회하는 조건 */) { /* 캘린더 날짜 하나씩 텍스트를 채워넣는 반복문 */ const handleClickDateOfCalendar = createHandleClickDateOfCalendar( dateOfCalendar, $d..