본문 바로가기
이론/Frontend

JavaScript의 값 - 1 (Value of JavaScript)

by 유세지 2021. 2. 17.

자바스크립트에는 여느 언어들처럼 배열과 문자열, 숫자 등을 값으로 가집니다. 그러나 일반 언어와는 다른 특성이 있어 이러한 값들을 사용할때 혼동을 줄 수 있기 때문에 정확하게 알고 사용하는 것이 중요합니다.

 

이번 시간에는 이런 독특한 특성을 가진 자바스크립트의 값에 대한 내용을 정리합니다.

 

배열

자바스크립트의 배열이 가진 특징 중 하나를 꼽으라면 무엇이든 값으로 들어갈 수 있다는 점을 꼽을 수 있습니다. 정수면 정수, 문자면 문자 등 한 배열에 들어가야 할 형식이 정해진 다른 언어와는 달리 숫자가 들어간 배열에 문자열을 추가하고, 심지어 객체나 다른 배열까지 집어넣을 수 있습니다.

 

특히 배열에 다른 배열을 집어넣는 방법은 자바스크립트에서 다차원 배열을 만드는 방법이기 때문에 잘 기억해두시는게 좋습니다. 배열을 선언할때 크기에 대한 제약도 따로 두지않기 때문에 이런 부분에선 확실히 다른 언어보다 편리하다는 느낌도 듭니다.

 

 

C에서의 동적 할당 예시, 이럴 필요가 없습니다.

 

 

여기서 주의해야 할 것은 빈 슬롯이 있는 배열입니다. 인덱스가 비어있다고 해도 문제 없이 실행은 되지만, 배열을 다룰때 비어있는 부분을 제대로 처리하지 않으면 의도한대로 동작하지 않을 수 있습니다.

 

빈 슬롯은 undefined가 출력됩니다.

 

비어있는 배열에는 쓰레기값이 들어가는 대신, 위의 사진처럼 undefined가 출력됩니다. 값이 들어있는지 유무에 상관없이 가장 뒤에 선언된 인덱스만큼의 길이 값을 갖는것도 확인할 수 있습니다.

 

다만 arr[1] 에 자동으로 들어간 undefined 는 명시적으로 arr[1] = undefined 라고 설정한 것과는 다름을 기억해야합니다. 가능하다면, 애초에 이렇게 구멍난 배열은 만들지 않는 것이 좋겠습니다.

 

 

배열에 관한 내용을 공부하던 중 새롭게 알게 된 사실인데, 배열의 인덱스를 숫자가 아닌 문자열로도 설정이 가능하다는 것입니다. 마치 json의 키-값 쌍처럼요.

 

이런것도 됩니다

 

물론 키 값으로는 문자열까지만 가능하고, raw한 문자를 넣는 것은 동작하지 않습니다.

 

이런건 안됩니다

 

문득 알파벳 한 글자만 넣으면 아스키 코드 값으로 변환되어서 들어가진 않을까? 라는 생각이 들어서 해봤는데 

 

역시 안됩니다

 

그런건 안되네요. 인덱스엔 멀쩡한 숫자값만 넣도록 합시다.

그럼에도 문자열 키를 통해서 값을 불러오고 싶다면 객체를 대용하는 것이 좋습니다.

 

 

한 가지 더. 배열과 비슷하지만 배열은 아닌 오브젝트, 유사 배열이 있습니다. 우리에게 익숙한 HTMLCollection이 대표적인 예시인데, 일반적인 배열 메소드를 적용하려고 하면 의도대로 작동하지 않습니다. 이를 진짜 배열로 다루고 싶을때에는 배열 유틸리티 함수를 이용해줍시다.

 

Array.prototype.slice.call(function.arguments); // deprecated!
Array.prototype.slice.call(arguments);
Array.from(arguments);

 

다만 여기서 function.arguments 를 사용해도 작동은 하지만 이 방법은 ES6를 기점으로 Deprecated 되었으니 함수 내의 지역변수인 arguments를 사용해주시면 되겠습니다.

 

MDN Deprecated and obsolete features

 

MDN Function.arguments

 

 

문자열

 

C에서의 문자열은 말 그대로 문자의 배열이었습니다. 따라서 문자열의 인덱스를 통한 요소의 접근이 가능했습니다.

 

 

그러나 자바스크립트에서의 문자열은 단순히 문자의 배열이 아닙니다. 배열이라면 당연히 지원해야할 인덱스를 통해 요소에 접근하는 방법도 모든 브라우저에서 지원하지는 않습니다. (ES5부터 추가된 기능입니다. IE10 이전 버젼에서는 불가능합니다.)

 

기본적으로는 charAt() 을 사용합니다.

 

가장 중요하면서 확실한 구분점으로는 문자열은 불변값(Immutable)이라는 것에 있습니다. 그에 반해 배열은 가변값(mutable)이죠. 배열이라면 요소를 수정할 수 있지만, 문자열은 내용을 수정할 수 없습니다.

 

따라서 문자열을 다루는 메소드들은 사실 내용을 바로 변경하는게 아니라 새로운 문자열을 생성해서 반환하는 과정을 거칩니다. 겉으로는 곧바로 조작할 수 있는 것처럼 보였지만 뒤에서는 복사 - 수정 - 반환의 단계를 밟았다는 점을 기억해두셔야 합니다.

 

 

숫자

자바스크립트의 숫자 타입은 정수형, 소수형을 따로 구분하지 않고 number 하나가 유일합니다. 이 말인 즉슨 자바스크립트에서는 정수와 소수를 구분하지 않는다는 말과 같습니다. 실제로 정수형으로 표시한 값과 소수형으로 표시한 값을 비교해보면 다음과 같은 결과를 얻을 수 있습니다.

 

 

이렇다보니 숫자에 대한 메서드를 사용할때면 이따금 뭔가 이상한 결과를 얻기도 합니다. 아래는 숫자 리터럴에 toFixed() 메소드를 적용한 결과입니다.

 

 

숫자의 표기 자리수를 결정하는 toFixed() 메소드가 숫자 변수 number에 적용했을때는 정상적으로 표시되는데, 숫자 리터럴에 직접 적용하려고 하면 오류를 출력합니다.

 

이런 현상이 발생하는 이유는 프로퍼티로 접근하기 위해 사용한 마침표 (.) 가 앞의 숫자 리터럴에 합쳐져 27.0 으로 해석되었기 때문입니다. 소수 형태의 값에 메소드를 적용하려 했지만 접근을 위한 마침표가 존재하지 않기 때문에 toFixed() 메소드를 찾지 못한 것입니다.

 

이를 해결하기 위해서는 마침표가 소수 표기를 위함이 아닌 프로퍼티로 접근하기 위해 사용한 것임을 분명히 해주면 됩니다. 다음과 같은 방법이 모두 가능합니다.

 

다양한 방법이 가능합니다

 

실제로 숫자에 메소드를 적용해야할 때는 오류 방지와 가독성을 위해 변수에 넣어서 사용하시고, 이런 식의 코딩은 다른 개발자를 골탕먹여주고 싶을때 유용하게 사용하시면 됩니다.

 

 

그 다음으로 소개할 내용은 아주 유명한 오류입니다. 자바스크립트 뿐 아니라 다른 언어들에도 비슷한 현상이 나타나기 때문에 이미 알고 계시는 내용일거라 생각합니다. 바로 이진 부동 소수점 숫자 문제입니다.

 

IEEE 754 표준을 따르는 언어라면 모두 일어나는 현상이고, 자바스크립트도 IEEE 754 표준을 따르기 때문에 피할 수 없는 오류입니다. 바로 확인해봅시다.

 

 

0.1 + 0.2 는 분명 0.3 인데도 불구하고, 콘솔은 false를 출력합니다. 간단히 말하면 부동 소수점으로 나타낸 0.1 과 0.2 는 실제 0.1, 0.2 와 일치하지 않기 때문에 발생하는 문제입니다.

 

이 오류에 대해 그렇게 깊이까지 알 필요는 없지만, 대신 이 숫자를 비교하는 방법은 알아두기로 합시다. 아주 작은 오차에 의해 발생하는 문제이므로, 이를 해결하기 위해 자바스크립트에선 이 오차를 머신 입실론이라는 이름으로 미리 정의해두었습니다.

 

ES6부터는 Number.EPSILON 으로 호출하여 바로 사용가능합니다. 없다면 Math.pow(2, -52); 를 머신 입실론으로 선언하여 사용하시면 됩니다.

 

 

 

 

계속해서 특수 값으로 이어집니다.

반응형

댓글