크롬 개발자 도구는 왜 가끔씩 거짓말을 할 까?

김동욱·2022년 12월 24일
0
post-thumbnail

본 포스팅은 Matthew MacDonald의 Why Chrome’s Developer Console Sometimes Lies를 번역 및 의역한 포스팅입니다.

게으른 평가(lazy evaluation)

바로 시작해보도록 하겠습니다.
여기 넘버 배열로 만들어진 자바스크립트 코드를 바꿔보겠습니다.
바뀌기 전 배열과 바뀐 후 배열이 로그에 출력됩니다.

const numbers = [2, 3, 4, 5];

console.log(numbers);

for (let i = 0; i<numbers.length; i++) {
    numbers[i] = numbers[i]**2;
}

console.log(numbers);

하지만 ‘for…of ’ 대신 ‘Array.map()’을 사용하는 것이 더 안전해보입니다.
왜냐하면 기존의 배열을 변경하는 것이 아닌 새로운 배열이 생성되기 때문입니다.
하지만 이 방법을 사용한 이유는 따로 있습니다.
그 이유는 개발자 도구에서 '게으른 평가'가 이뤄지기 때문입니다.

이 링크를 크로미움으로 동작하는 브라우저로 접속한 후(크롬, 엣지) 개발자 도구를 여새요.
그러면 두개의 배열리스트가 콘솔에 출력된 것을 볼 수 있습니다.
그런데 두개의 배열 모두 바뀐 후의 값을 가지고 있는걸 알 수 있습니다.

왜 이런 일이 일어날까요?
왜냐하면 console.log()는 실제로 배열을 참조하고 있기 때문이고
크롬은 메모리 방어와 최적화 문제를 이유로 우리가 콘솔창을 열 때까지 이전 정보를 잡아두지 않습니다.


'게으른 평가’를 피하는 법

최고의 예방법은 게으른 평가가 이뤄질 수 있다는 가능성을 항상 염두해 둬야하는 것이지만
진짜 문제는 이러한 문제가 예상치 못하게 나타나
콘솔에 출력된 게으른 평가가 된 정보 그대로 받아들여 질 수도 있다는점입니다!
그래서 우리는 게으른 평가를 항상 피하도록 노력을 하고 방법을 익혀야합니다.

게으른 평가를 피하는 몇가지 방법이 있습니다.

  1. 페이지를 로드하기전 콘솔창을 열어둡니다.
  2. 출력 되기 전 배열을 문자열로 변환합니다.
console.log(numbers.toString());

하지만 만약 배열안에 객체가 있다면 상황은 달라집니다.
여기 두개의 객체가 들어있는 배열이 있습니다.
두 객체중 하나를 바꿔보겠습니다.

const objects = [ 
  {name: 'Sadie', age: 12},
  {name: 'Patrick', age: 18}
];

console.log(objects);
objects[0].age = 14;
console.log(objects);

이번엔 콘솔창이 열려있어도 소용이 없습니다.
배열 내부의 최상위 계층은 게으른 평가가 이뤄지지 않겠지만
배열 내부의 객체는 쿼리가 닫혀진 상태여서 개으른 평가가 이뤄집니다!

objects.toString();
//'[object Object],[object Object]'

toString()을 쓴다해도 이렇게 출력되어 버립니다.
이 경우는 해결하는 방법 또한 있습니다.

  1. 스스로 로직을 잘(?) 작성하여 게으른 평가를 피한다.
  2. lodash같은 라이브러리를 사용한다.
  3. 아니면 JSON 함수를 사용한다.
  4. 원하는 결과물을 원시값으로 출력한다.
  • 추가: 최신 자바스크립트 버전에서 structedClone을 사용해도 됩니다.

여기까지 크롬의 게으른 평가 현상에 대하여 알아봤습니다.

profile
안녕하세요. 부산에서 근무하고 있는 프론트엔드 개발자 김동욱입니다. 영어 공부 겸 개발 공부를 위해서 글을 작성하고있습니다.

0개의 댓글