let found = [];
let parentElement = document.querySelector('body');
function check(checkHtml) {
if(checkHtml.classList && checkHtml.classList.contains(className)) {
found.push(checkHtml);
}
if(checkHtml.hasChildNodes()) {
for(let i = 0; i < checkHtml.childNodes.length; i++) {
check(checkHtml.childNodes[i]);
}
}
}
check(parentElement);
return found;
checkHtml.classList가 조건에 없으면 if문을 실행하지 않는 이유?
element Node에 classList method를 사용하게 되면 DomTokenList라는 것을 얻을 수 있다. DomTokenList이 contains라는 method를 가지고 있어서 아래와 같이 contains method를 사용할 수 있는 것이다.
if(checkHtml.classList.contains(className))의 경우
만약 checkHtml이 textNode일 경우 textNode에 classList 메소드를 실행시키면 undefined를 반환하게 된다.
undefined는 DomTokenList가 아닌 undefined를 반환하기 때문에 contains 메소드를 사용할 수 없다.
그렇게 때문에 오류가 발생하고, 오류가 발생한 코드 아래로는 실행되지 않음.
< 해결 방법 >
if(checkHtml.classList && checkHtml.classList.contains(className)) {
found.push(checkHtml);
}
위의 코드에서 checkHTML이 텍스트 노드일 경우
1. if의 조건이 true가 아니기 때문에 found.push(checkHTML)은 실행되지 않음
2. AND 연산자는 A && B에서 A가 false이면 A를 반환한다.
3. 그렇기 때문에 에러가 나지않고 undefined를 반환하고
4. 바로 아래의 if문도 실행가능!
### stringifyJSON 문제
- Broswer에 존재하는 JSON.stringfy 함수를 직접구현해보는 문제이다
- JSON.stringfy 함수는 input 값을 JSON 형식으로 변환합니다.
* 단, undefind와 function은 JSON으로 생략되거나 null 로 변환됩니다.
- stringfyJSON은 아래와 같이 작동합니다.
* Bolean이 input으로 주어졌을 경우
: stringifyJSON(true); // 'true'
* String이 input으로 주어졌을 경우
: stringifyJSON('foo'); // '"foo"'
* Array가 input으로 주어졌을 경우
: stringifyJSON([1, 'false', false]); // '[1,"false",false]'
* Object가 input으로 주어졌을 경우
: stringifyJSON({ x: 5 }); // '{"x":5}'
* undefind, function이 주어졌을 경우
: stringifyJSON(undefined) // undefined
: stringifyJSON(function(){}) // undefined
: stringifyJSON({ x: undefined, y: function(){} }) // '{}'
```js
function stringifyJSON(obj) {
if(typeof obj === 'number' || typeof obj === 'boolean' || obj === null) {
// 숫자, boolean, 값자체가 null일 경우 문자화
return String(obj);
} else if (typeof obj === 'string') {
// 타입이 문자일 경우 원래 문자에 ""를 더한다.
/* JSON.stringify()에 문자열 값을 넣을 경우,
문자열 값 자체가 문자열이 되기 때문이다. */
return `"${obj}"`;
} else if (Array.isArray(obj)) {
// 배열의 길이가 0일 경우 빈배열 반환
if(obj.length === 0) {
return '[]';
} else {
let result = [];
for(let elem of obj) {
// stringifyJSON 함수에 배열의 각 요소 넣고 실행(재귀)
// stringifyJSON 함수 실행으로 반환된 값을 result에 push
result.push(stringifyJSON(elem));
}
return `[${result}]`;
}
} else if (typeof obj === 'object') {
if(Object.keys(obj).length === 0) {
return '{}';
} else {
let result = [];
for(let key in obj) {
if(typeof obj[key] === 'undefined' || typeof obj[key] === 'function') {
/* obj[key]가 undefined이거나 function이면 제거한 후
stringifyJSON 함수 실행 (재귀) */
delete obj[key];
stringifyJSON(obj);
} else {
result.push(`${stringifyJSON(key)}:${stringifyJSON(obj[key])}`);
/*
객체의 key와 value를 stringifyJSON 함수에 넣고 실행,
반환된 값을 a:b의 형태로 조합하여 result에 push
*/
}
}
return `{${result}}`;
}
}
};