어제, wordle 제작 중 오류를 부분적으로 해결하였다.
2023.12.06 기록 (wordle 부분적 문제 해결)
https://gidalim4u.tistory.com/2 2023.12.5 기록 (자주 쓰는 VSC 단축키, wordle 만들어보기) 유용하게 쓸만한 vsc의 단축키(shortcut)을 기록했다. Javascript로 게임을 만들 때 자주 사용되는 반복문을 접해보았다. c
gidalim4u.tistory.com
해결해야 하는 문제는 두 가지였다
- 포함여부를 판단하기 위한 'includes' 에서 아무것도 적지 않은 공백을 true로 출력하는 것을 확인
이것이 정상적인 작동이면 해결법 또한 확인 - 디버깅을 하는 방법을 배우기
가장 먼저
includes 는 공백을 true로 출력하는지에 대한 의문을 해결하기 위해 실험을 해보았다.
<script>
var sonetto = 'vertin';
console.log(sonetto.includes(''));
// true 출력. 왜 공백인데 true인것이지
</script>
한국어로 검색시, includes 를 사용하는 방법이 주된 결과물이었기에
영어로 검색을 해보았다.
생각보다 같은 이유로 의문을 가진 사람들이 많았다.
https://stackoverflow.com/questions/51596236
when I pass an empty string into includes("") will it always return true?
So, I am testing the JS includes() method, so I created a search input field, where I can search through the notes I created with live rerendering. Now my question is: When I pass no searchtext at...
stackoverflow.com
주된 내용은 다음과 같다.
.includes 함수는 .indexOf 함수와 일치해야한다. 또한 .indexOf는 항상 공백문자열과 일치해야한다.
가장 먼저 .indexOf 에 대해서 알아보도록 하였다.
String.prototype.indexOf()
JavaScript에서 indexOf는 보통 string.indexOf(찾고자하는 값, 시작위치)로 사용되며,
위치는 기본값을 0을 시작으로 시작지점에 두고, 음수는 뒤에서부터 범위를 시작한다.
단, 이때 진행방향은 왼쪽에서 오른쪽으로 동일하게 진행한다.
출력값은 찾고자하는 값의 위치 (첫 번째가 0이다)
이게 아주 기가막혔다.
const array = [1, 3, 6];
array.indexOf(1); // 0 1이라는 값은 0번째에 위치해 있음
array.indexOf(7); // -1 7이라는 값은 찾을 수 없으므로 -1을 출력한다
array.indexOf(6, 2); // 2 6에서 검색을 시작 찾았으므로 해당위치인 2를 출력 (6은 2번째에 존재하므로)
array.indexOf(1, -1); // -1 -1 즉 6에서부터 검색을 시작할 때 1은 찾을 수 없으므로 -1을 출력한다.
array.indexOf(1, -3); // 0 -3 즉 0번째부터 검색을 시작, 찾았으므로 해당 위치인 0을 출력
단순한 궁금함으로 이 음수값을 계속 늘리면 어떻게 되는지 궁금했고, 늘려본 결과 다음과 같았다.
const array = [1, 3, 6];
array.indexOf(1, -4); // 0
array.indexOf(1, -5); // 0
array.indexOf(1, -6); // 0
array.indexOf(3, -2); // 1
array.indexOf(3, -3); // 1
array.indexOf(3, -4); // 1
위치가 계속 밀리면서 음수의 전체범위를 넘어가자 해당 인덱스 값을 번째를 계속 출력하였다.
0(시작점)을 기준으로 경계선을 긋고, 음수는 자리의 오른쪽에서 시작하되 0을 침범하지 않는다.
즉 -1은 6의 값부터 값을 탐색하니 6을 제외하곤 아무것도 찾을 수 없다 라는 값이 나오고
-2는 3부터 검색을 하므로 3과 6을 찾을 수 있다. (그렇기 때문에 array.indexOf(3, -2); // 1 의 값은 올바른 위치인 1을 출력)
음수값이 아무리 커져봐야(숫자가 계속 작아져 봐야) 검색의 범위는 array 전체에 해당하므로 올바른 위치를 출력한다.
그럼 반대로 양수로 계속 커지면 어떻게 될까
const array = [1, 3, 6];
array.indexOf(3, 4); // -1
array.indexOf(3, 5); // -1
array.indexOf(3, 6); // -1
array.indexOf(3, 50); // -1
array.indexOf(3, 100); // -1
당연하게도(?) 범위 밖에서 찾는다고 하니 찾을 수 없다는 -1을 일괄 출력한다.
indexOf를 사용할 땐 꼭 왼쪽에서 오른쪽으로 라는 걸 잊지 않으면 좋겠다 .
이제는 .includes에 대해 알아보려고 한다. '공백 문자열'은 항상 일치하기에 true값을 가진다.
이 부분에 있어서는 일관성을 가지기 위해서 라고 하는데, 정확하게 쓰이는 목적을 알기 전까지는 참고만 해두는 것이 좋을 것 같다.
또한, 찾아보면서 공백을 true 값으로 하지 않는 추가 함수를 달아준다면 문제가 해결되는 것을 발견 할 수 있었다.
String.prototype.includes = function (subStr) {
if (subStr.length == 0 || this.indexOf(subStr) === -1) {
return false;
}
return true;
};
String.prototype.includes()
위의 코드를 얻음으로써 문제점을 해결할 수 있는 실마리를 찾았다. 다만, String.prototype.includes()를 사용 한 것에 있어서 차이점이 무엇이 있는지 알아보고 사용하기로 했다.
직접 해당 문서를 찾아보면 String.includes()와 같은 설명이 나오게 된다. 두 개의 차이점이 궁금해 열심히 검색을 해보았지만, 키워드 문제 탓인지 결과를 얻기 힘들어 chat GPT를 이용해 구체적인 차이점에 대해서 물어보았다.
같은 내용이라고 한다. 다만, 결과를 적용시켜보고 다른 부분을 알게되었다.
</style>
<input class="enter">
<input class="enter">
<input class="enter">
<input class="enter">
<input class="enter">
<button>제출</button>
<script>
var answer = 'abcde';
String.prototype.includes = function (subStr) {
if (subStr.length == 0 || this.indexOf(subStr) === -1) {
return false;
}
return true;
};
document.querySelector('button').addEventListener('click',
function () {
var enter = document.querySelectorAll('.enter');
for (let i = 0; i < 5; i++) {
if (enter[i].value == answer[i]) {
enter[i].style.background = 'green';
} else if (answer.includes(enter[i].value)) {
enter[i].style.background = 'yellow';
} else {
enter[i].style.background = 'lightgrey';
}
enter[i].classList.remove('enter');
}
var template = `<div>
<input class="enter">
<input class="enter">
<input class="enter">
<input class="enter">
<input class="enter">
</div>`;
document.querySelector('body').insertAdjacentHTML
('beforeend', template);
console.log(enter);
})
</script>
String.prototype.includes 를 적용한 문장에서는 원래 유도한 값과 같게 빈칸은 회색으로 출력이 되었다
하지만 String.includes 즉 prototype를 제거한 문장에서는 이전과 같은 버그가 발생했다.
String.includes = function (subStr) {
if (subStr.length == 0 || this.indexOf(subStr) === -1) {
return false;
}
return true;
};
문제가 된 부분을 통해 다시 한 번 더 chatGPT에게 차이를 물었다.
프로토 타입 체인과 메서드 호출 방식의 차이로 인해서 적용이 되지 않는 것이라고 한다.
wordle 자체의 문제는 해결되었다. 추가 기능구현만 남은 셈이다.(스펠링을 하나만 넣기, 추가 단어를 부여하도록 하기 등등)
하지만 메서드 호출방식이라는 문구를 듣고 객체에 대해서 조금 더 공부가 필요함을 느꼈다.
해당 항목을 확실히 다진 뒤에 wordle의 추가 구현작업을 진행하고자 한다.
해결해야할 문제
- String.includes('') (즉, 공백)이 true 값을 가지는 이유.
- 객체에 대한 개념학습
- 해당 문서를 해석하기 위한 논리 연산자 개념학습
'JavaScript' 카테고리의 다른 글
2023.12.15 기록 (javascript 연산자) (1) | 2023.12.15 |
---|---|
2023.12.11 기록 (javascript 객체 기초) (1) | 2023.12.11 |
2023.12.8 기록 (String.prototype.includes) (0) | 2023.12.11 |
2023.12.6 기록 (wordle 부분적 문제 해결) (0) | 2023.12.06 |
2023.12.5 기록 (자주 쓰는 VSC 단축키, wordle 만들어보기) (0) | 2023.12.05 |