Array.forEach()
로 반복문을 작성하다가, forEach()
는 중도에 실행을 멈추고 싶을 땐 사용하기 적절하지 않다는 걸 깨달았다. 해결법을 찾아보니 some()
을 이용할 수 있었다.
[ Array.prototype.forEach() | MDN ]
'...예외를 던지지 않고는 forEach()를 중간에 멈출 수 없습니다. 중간에 멈춰야 한다면 forEach()가 적절한 방법이 아닐지도 모릅니다. 다른 배열 메서드, every(), some(), find(), findIndex()는 배열 요소를 판별 함수에 전달하고, 그 결과의 참/거짓 여부에 따라 반복의 종료 여부를 결정합니다. ...'
다음은 트리 구조로 이루어진 객체를 탐색하며, 인자로 전달받은 key값을 가진 첫 번째 객체를 찾아 반환하는 함수이다. 이 함수에서 forEach()
를 사용하면, 일치하는 객체를 찾았음에도 그 뒤에 함수를 다시 호출해 나머지 객체를 탐색하기 때문에 result
가 null
로 리셋되어 바른 결과를 리턴하지 않는다.
대상 배열
const seasoning = [
{
number: 1,
name: 'sugar'
},
{
number: 2,
name: 'pepper',
friend: [
{
number: 3,
name: 'salt'
},
]
}
];
함수 getObjectByKey
function getObjectByKey(array, name) {
let result = null;
array.forEach((obj) => {
if (obj.name === name) {
result = obj;
}
if (obj.friend) {
result = getObjectByKey(obj.friend, name);
}
});
return result;
}
getObjectByKey(seasoning, 'sugar');
// null
이를 some()
을 사용하는 코드로 수정했다. some()
은 return
값이 true
이면 그 시점에 동작을 멈춘다. 그래서 일치하는 객체를 발견한 뒤 true
를 return
하도록 했다.
function getObjectByKey(array, name) {
let result = null;
array.some((obj) => {
if (obj.name === name) {
result = obj;
return true;
}
if (obj.friend) {
result = getObjectByKey(obj.friend, name);
}
});
return result;
}
getObjectByKey(seasoning, 'sugar');
// {name: "sugar"}
setInterval()
메서드가 함수를 호출하는 시간 간격을 무작위로 설정하고 싶었다. 여러가지로 시도하다가 잘 풀리지 않아 방법을 찾아보니, setTimeout()
을 재귀적으로 호출하면서 시간을 랜덤하게 설정하는 방법이 있었다.
const randomCall = () => {
console.log('Hello!')
setTimeout(randomCall, Math.floor(Math.random() * 8000));
}
randomCall();
[ : 문서-레벨의 메타데이터 요소 | MDN ]
HTML<meta>
요소는 <base>
, <link>
, <script>
, <style>
또는 <title>
과 같은 다른 메타관련 요소로 나타낼 수 없는 메타데이터를 나타낸다.
viewport
는 모바일 기기에만 적용되는 메타데이터 요소로, content
속성에서 viewport
사이즈와 관련된 값들을 정의할 수 있다. CSS 상에서 media query를 설정했더라도, HTML 파일 내에 viewport
요소가 없다면 모바일 화면에서 올바르게 적용되지 않는다.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
a
태그의 href
속성을 ../
로 설정하면 상위 폴더로 이동하는 링크를 만들 수 있다.
<a href="../index.html">Back to List</a>
[ CSS 객체 모델 (CSSOM) | MDN ]
[ Using dynamic styling information | MDN ]
CSS Object Model은 자바 스크립트에서 CSS를 조작 할 수있게 해주는 API 세트다. CSS의 경우 DOM와 HTML API의 펜던트이며, 이를 통해 CSS양식을 동적으로 읽고 수정할 수 있다.
아래 코드는 HTML 엘리먼트에 설정된 background-colo
값을 red
로 변경한다. document.styleSheets[0].cssRules[0]
를 통해서 접근하는 style
값은 인라인 스타일이 아니라, CSS 스타일 시트에 저장된 값이다.
const stylesheet = document.styleSheets[0];
// document.styleSheets[0]은 CSS 의 Style Sheet이다.
stylesheet.cssRules[0].style.backgroundColor="red";
// cssRules[0]은 여기서 html 엘리먼트이다.
CSS rules는 유사배열로, CSS 스타일 시트에 작성한 스타일 룰들이 작성 순서대로 나열되어 있다. 예를 들어, 아래와 같은 CSS 스타일 시트가 있다면 :
html {
text-align: center;
}
body {
margin: 0;
min-height: 100vh;
}
.clock {
width: 30px;
height: 30px;
}
CSS rules의 내용은 다음과 같다.
document.styleSheets[0]
// CSSStyleSheet {ownerRule: null, cssRules: CSSRuleList, rules: CSSRuleList, type: "text/css", href: null, …}
document.styleSheets[0].cssRules
// CSSRuleList {0: CSSStyleRule, 1: CSSStyleRule, 2: CSSStyleRule, length: 3}
// 0: CSSStyleRule {selectorText: "html", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "html { text-align: center; }"}
// 1: CSSStyleRule {selectorText: "body", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "body { margin: 0px; min-height: 100vh; }"}
// 2: CSSStyleRule {selectorText: ".clock", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: ".clock { width: 30px; height: 30px; }"}
현재 Chrome 브라우저(버전 78 확인)에서는 서버 없이 로컬에서 CSS rules에 접근할 수 없다. 로컬 파일시스템에서 CSS rules를 로드하는 건 Cross-Origin Resource Sharing (CORS) 정책에 어긋난다.
[ JavaScript 30 Day1, Day2 | 윤슬기 ]
이번주에는 자바스크립트를 배우는 코스 JavaScript 30을 시작했다. 배운 점과 응용해 만든 결과물을 시리즈로 정리해나간다.