분류 전체보기 49

부동 소수점 연산의 함정

모르면 언젠가 한 번은 당할 수밖에 없는 것 0.1 + 0.2 === 0.3 그동안 컴퓨터로 계산한 0.1 + 0.2의 결과가 0.3이 아니라는 정도로만 알고 있었지 실제로 크게 당해본 적은 없었습니다. 보통의 경우에는 값이 안 맞는다 싶을 때, 적절한 소수점 자리에서 반올림으로 처리하면 올바르게 보정됩니다. 반올림은 괜찮지만... 이 미세한 오차로 인한 진짜 문제는 반올림 연산이 아닌 내림 연산 또는 올림 연산을 사용할 때 본격적으로 발생합니다. 위의 수를 소수점 아래 셋째 자리에서 반올림 · 올림해야 한다고 생각해 봅시다. 자바스크립트로는 아래와 같이 수행할 수 있습니다. let number = 1.1 * 1.1; number; // 1.2100000000000002 Math.round(number ..

함정 시리즈 2023.11.19

[JavaScript] 0과 -0 (JavaScript 정수 자료형의 함정)

정수 자료형? 그런 건 따로 없소이다. 모든 것은 숫자(Number)로 통합니다. -0 만들기 작업에 큰 지장은 없지만 직접 마주한다면 은근히 거슬리는 -0이라는 녀석, 이 녀석은 어떻게 생길까요? 직접 -0을 입력 부호가 마이너스이면서 곱셈의 결과가 0이 되도록 하기 -0; -1 * 0; 1 * -0; 0 * -0; -0을 마주하게 된 배경 구현한 자료구조가 제대로 동작하는지 확인하기 위해 정수 범위에 걸친 랜덤한 데이터가 필요했습니다. 데이터를 만들기 위해 아래와 같은 로직을 통해 임의의 수를 생성하였습니다. (반복문 생략) const N = 100; // 숫자 범위 조정 (Math.round(Math.random())) * 2 - 1) * Math.floor(Math.random() * N); //..

함정 시리즈 2023.11.09

[JavaScript] Set.prototype.add()의 함정

Set.prototype.add()는 Array.prototype.push()와 달리 오직 하나의 전달인자만을 추가할 수 있습니다. 1. 메서드 호출 구문 mySet.add(value); // 예시 mySet.add(1); mySet.add('hi'); // 잘못된 예시 mySet.add(1, 'hi'); // 집합에는 1만 추가되며, 'hi'는 무시됩니다. arr.push(element1[, ...[, elementN]]); // 예시 arr.push(1); arr.push(1, 'hi', [0]); 2. 전달인자 개수 메서드 전달인자 개수 Set.prototype.add 1 Array.prototype.push N 3. 전달인자를 생략한 경우 const mySet = new Set(); mySet.a..

함정 시리즈 2023.11.07

[기록] 윈도우 MySQL ↔ ubuntu node.js(mysql2) 연결 시도

요약 MySQL 연결에 어려움을 겪는 경우 해볼 수 있는 갖가지 방법 적용 socat을 사용하여 소켓 통신을 시도하였으나 배경지식 부족으로 인하여 실패 socat을 통하여 ubuntu localhost:3306 - pc ip 주소:3306 연결 sql 요청 host로 pc ip 주소를 직접 입력하여 socat을 거치는 불필요한 단계 제거 상황 MySQL 서버를 윈도우에서 실행중 동일한 기기의 WSL2 ubuntu 환경에서 node.js(mysql2)를 활용하여 데이터베이스 접근 시도(localhost:3306) -111: ECONNREFUSED 오류 발생 code: 'ECONNREFUSED', errno: -111, sql: undefined, sqlState: undefined, sqlMessage: ..

[로컬 개발 환경] 윈도우 MySQL ↔ ubuntu node.js(mysql2) 연결 오류 해결

-111: ECONNREFUSED 윈도우 환경에서 실행중인 MySQL 서버와 동일한 디바이스의 ubuntu 환경에서 실행중인 node.js를 연결합니다. 두 환경 모두 로컬 환경입니다. 준비물 네트워크 연결 요약 두 환경 모두 로컬이지만 서로 분리되어 있으므로 로컬호스트 주소가 아닌 컴퓨터의 ip 주소를 통해 접근해야 했습니다. 외부 데이터베이스 서버에 접근하는 것처럼요. 해결 1. 서버 호스트 변경 요청 대상 호스트 주소를 MySQL이 실행중인 PC의 ip 주소로 변경합니다. const pool = mysql.createPool( { host: 'localhost', // 이 부분을 '172.xxx.xxx.xxx'로 변경하였습니다. user: 'user', database: 'db', password:..

[JavaScript] new Array(3).fill([]) - 참조 자료형의 함정

문제 // 길이가 3인 배열을 만들어 빈 배열을 채웁니다. const arr = new Array(3).fill([]); // arr의 첫 번째 배열에 요소를 추가합니다. arr[0].push(1); arr; // [[1], [1], [1]] ? 오직 0번 인덱스의 배열에만 접근하여 값을 추가했음에도 불구하고 모든 배열에 값이 추가되었습니다. 이는 곧 fill 메서드의 적용 결과로써 각각의 인덱스에 대하여 새로운 배열이 할당된 것이 아니라 메서드의 인자로써 전달된 배열 하나만으로 모든 자리를 채웠다는 이야기가 됩니다. 모든 인덱스가 동일한 배열에 대한 참조를 가지고 있었기 때문에 발생한 문제입니다. 해결 fill 메서드를 호출한 뒤 map 메서드를 통해 배열을 할당합니다. map 메서드를 사용하면 map..

함정 시리즈 2023.09.23

[TypeScript] TS7053 - Object.keys()

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Filters'. No index signature with a parameter of type 'string' was found on type 'Filters'. 객체의 값에 접근하기 위해 사용한 key가 인터페이스, 타입 정의에 사용된 key의 범위를 벗어나기 때문에 발생하는 오류 문제 Object.keys 메서드를 통해 얻은 key 배열에 대하여 forEach 메서드로 순회 시도 forEach문의 인자로 개별 key에 대한 접근 시도 이 때, forEach문 내부의 값은 무조건 객체가 가지는 key일 것으..

[JavaScript] new Array().fill().map() - 빈 슬롯 참조 방식

문제 특정 길이를 가지는 새로운 배열을 생성한 후 fill 메서드를 사용하지 않으면 map으로 배열을 순회하더라도 배열의 인덱스에 접근할 수 없습니다. Array 생성 직후 map 호출 new Array(3).map(v => new Array(3).fill(0)); // [ ] fill 메서드 호출 후 map 호출 new Array(3).fill().map(v => new Array(3).fill(0)); // -> [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ] 이러한 차이는 배열의 빈 슬롯에 대한 참조 방식이 달라서 발생함을 알게 되었습니다. 빈 슬롯(empty)에 대한 참조 방식 메서드가 배열의 빈 슬롯을 참조하는 방식은 다음의 두 가지로 나뉘며, 일관적이지 않습니다. 빈..

[JavaScript] String.prototype.replace - undefined가 삽입되는 문제

문제 문자열로부터 정규표현식에 해당하는 부분을 제거하려 하였으나, undefined가 삽입되는 현상이 발생하였습니다. replace 함수의 두 번째 인자가 생략되었기 때문입니다. // 반복문 내부 코드 // 탐색 대상 letter 정규표현식 생성 const regexp = new RegExp(letter, 'g'); // 발견된 문자열의 개수를 결과에 더하기(옵셔널 체이닝 ?, null 병합 연산자 ?? 사용) result += input.match(regexp)?.length ?? 0; // input으로부터 검사 완료된 문자열을 전부 제거 input = input.replace(regexp); // ddz=z= // dundefinedz= // dundefinedundefined 해결 replace ..

window.location.origin - 웹사이트 기본 주소(origin) 가져오기

문제 상황 내 애플리케이션의 기본 주소에 어떻게 접근할 수 있을까? 당신... 이제는 브라우저의 주소창도 확인할 줄 모르게 된 것이오? 라고 생각하실 수 있지만 로컬 환경에서 루트 디렉토리로써 http://localhost:3000/와 같이 주소를 작성하여 테스트를 통과한다 한들 테스트 환경이 달라지면 해당 주소는 무용지물이 되어버리고 맙니다. 그래서 현재 실행중인 환경의 주소에 접근할 수 있는 방법이 필요했습니다. 해결 window.location.origin origin으로 접근하면 프로토콜과 호스트로 구성된 문자열을 반환합니다. origin은 출처를 의미하며, 프로토콜://호스트:포트번호로 구성되지만 http 프로토콜은 80번, https 프로토콜은 443번 포트를 사용하는 경우 포트 번호가 생략되..