개발 기술/사소하지만 놓치기 쉬운 개발 지식

배열판별법, JSON.parse, padStart, querySelector 성능

by GicoMomg (Lux) 2021. 9. 12.

이번 시간에는
- 1. 배열 판별법
- 2. JSON.parse를 하지 않아도 되는 경우
- 3. padStart로 특정 문자열 붙이기
- 4. 객체에 바로 키 값 객체 넣기
- 5. querySelector와 getElementById의 성능에 대해 알아보자!

1. array(배열) 판별하기

: 작업을 하다보면, 이 데이터가 배열인지 확인해야할 때가 있다.
: 한 예로 slice()함수는 배열에서만 실행되는 함수이므로,배열이 아니면 실행시키면 안된다.

const variable = 어떤 형태의 값;

// 배열에서만 실행되는 함수
if(배열이라면) return variable.slice(1, 2);  

그렇다면 typeof를 이용해 배열인지 판별하면 되지 않을까?

: 안타깝게도 js에서는 array, object의 타입이 둘 다 object이다!!

const arr = [1,2,3];
const obj = {'hello':'world'};

console.log(typeof arr, typeof obj)  //object. object

그러니까 Array.isArray를 사용하자!

: Array.isArray는 해당 변수가 배열이면 true, 아닌 경우 false를 리턴한다.
: 앞선 본 예시에 해당 함수를 사용하면 아래와 같이 사용할 수 있다.

const variable = 어떤 형태의 값;

// 배열에서만 실행되는 함수
if(Array.isArray(variable)) return variable.slice(1, 2); 

2. string은 JSON.parse를 하지 않아도 된다!

: 우리는 JSON문자열을 js에서 이용해야할 때가 있다.
: 만약 로컬스토리지에 저장된 변수를 불러와 js에서 처리하고자 한다면?
: 우리는 JSON.parse를 사용하곤 한다.

// local에 저장된 값: 'number:{"first": 1}'

let localValue = localStorage.getItem('number'); //로컬에서 키로 값을 가져옴
localValue = JSON.parse(localValue);    

console.log(localValue.first + 1);   //2

그렇다면 local에 저장된 값을 js에서 사용하려고 할 때,
string, number, boolean도 다 JSON.parse를 해줘야 할까?

: string 형태의 데이터는 JSON.parse를 하지 않아도 된다.
: 하지만 그 이외의 형태(아래 예시)들은 JSON.parse를 해야 사용할 수 있다.

//object
JSON.parse('{}');              // {}
//boolean
JSON.parse('true');            // true
//array
JSON.parse('[2, 45, "true"]'); // [2, 45, "true"]
//null
JSON.parse('null');            // null

: 추가적으로, JSON.parse를 할 때 아래와 같이 값 마지막에 ,가 있을 경우 SyntaxError가 발생한다.

JSON.parse('[1, 2, 3, 4, ]');  //4뒤에 쉼표가 있어 SyntaxError
JSON.parse('{"foo" : 1, }');   //1뒤에 쉼표가 있어 SyntaxError

3. 문자열 끝에 특정 문자열 채우기

: new Date()로 현재 시각을 받아, 특정 형태로 나타내고자 한다.
: 이때, 10보다 작은 시간에는 0을 붙여 01시로 표현하고, 10보다 큰 시간은 그대로 표현하고자 한다.
: 만약 조건문을 사용한다면 아래와 같이 쓸 수 있다.

let result;
const time = new Date();
const hours = time.getHours();   

result = (hours < 10) ? `0${hours}` :  hours;  //10보다 작으면 앞에 0을 붙임
console.log(result);

: 이렇게 시간만 나타내니 코드가 길지 않아 보인다.
: 하지만 시&분&초 모두 0보다 작을 경우, 앞에 0을 붙이려고 한다면?
: 앞선 방법처럼 조건문을 쓰면 아래와 같이 코드가 길어진다.

const time = new Date();
let hours = time.getHours();   
let minutes = time.getMinutes();
let seconds = time.getSeconds();

//10보다 작으면 앞에 0을 붙임
hours = (hours < 10) ? `0${hours}` :  hours;  
minutes = (minutes < 10) ? `0${minutes}` :  minutes; 
seconds = (seconds < 10) ? `0${seconds}` :  seconds; 
console.log(`${hours}시 ${minutes}분 ${seconds}초`);  //01시 32분 02초

다행히도 js에서는 padXXX()로 문자열 끝에 특정 문자열을 채울 수 있다.

padStart(문자열 길이, 특정 문자열) padEnd(문자열 길이, 특정 문자열)
- 문자열에 특정 문자열을 채워, 주어진 길이를 만족하는 문자열을 반환
- 채워넣기는 대상 문자열의 끝(좌측)부터 적용
- 문자열에 특정 문자열을 채워, 주어진 길이를 만족하는 문자열을 반환
- 채워넣기는 대상 문자열의 끝(우측)부터 적용
//padStart예시
const str1 = '3';
console.log(str.padStart(2, '0')); // "03"

const str1 = '700';
console.log(str.padStart(6));      // "   700"
//padEnd예시
const str1 = '12345';
console.log(str1.padEnd(7, '+'));  //"12345++"

const str2 = '200';
console.log(str2.padEnd(5));       // "200  "

: 조건문을 사용하던 시&분&초는 padStart로 표현하면 아래와 같이 간단해진다!

const time = new Date();


//문자의 길이가 2가 되도록 앞에 0을 붙임
let hours = time.getHours().toString().padStart(2, 0);   
let minutes = time.getMinutes().toString().padStart(2, 0);
let seconds = time.getSeconds().toString().padStart(2, 0);  


console.log(`${hours}시 ${minutes}분 ${seconds}초`);  //01시 32분 02초

4. 객체에 바로 키:값 객체 할당하기

: 만약 인자로 키와 값이 오고, 이 키값을 새 객체에 담아야 한다면 어떻게 해야할까?
: 아래와 같은 방법으로 하면 과연 내가 원하는 객체가 나타날까?

const obj = {1: 'hello'};
function newObj(key, value) {
  const newObj = {...obj, key:value };
  console.log(newObj);
}

newObj(2, 'bye'); 

: 안타깝게도 (A)처럼 작성하면 js는 (B)형태로 인식한다🥲

const newObj = {...obj, key:value };     //(A)
const newObj = {...obj, 'key':value };   //(B)


//(A), (B)의 결과 : {1: 'hello', 'key': 'bye'}

: 그렇다고 아래 예시처럼 매번 새로운 객체를 선언해서 할당하는 건 귀찮다!

let argObj = {};                       //새 객체 선언
argObj[key] = value;                   //{key:value} 객체 생성
const newObj = {...obj, ...argObj };   //할당

: 그럼 다른 방법은 없는걸까? 아니다! [key]:value를 사용하면 된다! 👍

const obj = {1: 'hello'};
function newObj(key, value) {
  const newObj = {...obj, [key]:value };   //this!!
  console.log(newObj);
}

newObj(2, 'bye');     //{1: 'hello', 2: 'bye'}

5. querySelector, getElementById의 성능 차이

: 우리는 dom에 접근하기위해 id값을 이용한 getElementById를 쓰거나,
class값을 이용한 getElementsByClassName를 쓰곤 한다.

<html>
  <p id="unique" class="className"></p>
</html>

document.getElementById('unique');              //id 접근법
document.getElementsByClassName('className');   //class 접근법

: 또 다른 방법으로는 querySelector를 사용한다.
: querySelector의 장점은 클래스든 아이디든 상관없이 가지고 올 수 있다는 점이다.

<html>
  <p id="unique" class="className"></p>
</html>

document.querySelector('#unique');           //#id로 접근
document.querySelector('.className');        //.class로 접근

그렇다면 우리는 dom에 접근할 때 어떤 함수를 쓰는 게 더 효율적일까?
아래 사진은 querySelector와 getElementById의 성능차에 대한 내용이다.
이미지 출처로 가서 글 더 보기

: 그럼 querySelector는 쓰레기일까?
: 성능에 관한 해당 글을 요약하면 아래와 같다.

  • querySelector는 초당 약 칠백만(7,000,000) 건의 작업을 처리한다.
  • querySelector가 getElementById보다 느린거지, 절대적으로 느린 속도는 아니다.
  • querySelector는 id, class로 dom에 접근할 수 있기에 다양성이 높다.

: 굳이 결론을 내리자면...

오직 성능을 우선으로 여긴다면 getElementById를,
개발 편의성과 생산성을 우선한다면 querySelector를 선택해라!

: 하지만 이 결론이 불문율은 아니다! 명심!!

출처
아래 출처로 가면 더 많이 알 수 있다구! 🧐

반응형

댓글