728x90
728x90

이 글은 <모던 자바스크립트 딥 다이브> 라는 책을 읽고 필자가 재구성하여 작성한 글입니다.

데이터 타입의 필요성

데이터 타입은 왜 필요한 것인가?

🙋‍♀️ : 데이터 타입에 의한 메모리 공간 확보와 참조를 위해

값은 메모리에 저장하고 참조할 수 있어야 한다. 메모리에 값을 저장하려면 먼저 확보해야 할 메모리의 크기를 결정해야 한다.

이렇게 숫자 타입 값이 할당된다.

자바스크립트는 숫자 타입의 값을 생성할 때 배정밀도 64비트 부동소수점 형식을 사용한다. 따라서 실제로 메모리에 저장되는 2진수 값은 위 그림과 다른다. 지금은 간단히 양의 정수로 저장된다고 생각하자

→ 64비트 부동소수점 형식에 관해서는 이전에 다뤄보았다.

🤔 : 값을 생성할 때? 명확한 기준이 없어 조금 헷갈리는걸??

→ 값을 생성할 때란 무엇인가???

프로그램이 실행되는 동안 변수에 할당되거나, 연산이 이루어지거나, 함수가 실행되면서 새로운 값을 만든다는 것을 의미

→ 변수를 선언하고 값을 할당하는 경우

→ 연산을 수행하는 경우

→ 함수를 실행하는 경우

즉 “자바스크립트에서 값을 생성한다” 는 것은 프로그램이 동작하면서 새로운 값을 만들고 변수에 저장하거나 결과로 반환하는 행위를 말한다.

🤷 : 자바스크립트에서 참조한다는 것은?

  • 변경이 가능한 값의 의미이다
  • 객체를 가리키는 변수를 다른 변tn 에 할당하면 원본의 참조 값이 복사되어 전달된다.

자바스크립트에서 참조(Reference)는 변수가 객체나 배열과 같은 데이터 구조에 대한 메모리 주소를 가리키는 것을 의미한다. 다른 말로 하면, 참조는 실제 데이터가 위치한 메모리 영역에 직접 접근하는 것이 아니라, 데이터가 위치한 주소를 통해 해당 데이터에 접근하는 방법을 제공한다.

객체를 선언하여 생성한다

const originalObject = {name : "insidepixce", age : 20};

변수 object가 originalObject를 가리킨다

const referenceObject = originalObject;

referenceObject를 통해 Originalobject의 속성에 접근하고 수정한다

referenceObject.age = 21;

이때 originalObject와 referenceObject는 같은 객체를 가리키고 있다. 따라서 ‘referenceObject’를 통해 해당 객체의 속성을 수정하면 Original Object속의 속성도 같이 변경된다. 이는 객체의 데이터가 복사되지 않고 메모리 주소를 공유하기 떄문이다.

  • 참조는 배열에서도 마찬가지로 동작한다

즉, 식별자를 통해 메모리 공간의 주소를 찾아가는 것이다. 이때 값을 참조하려면 한번에 메모리를 몇 개를 읽어들여야 할지, 즉 메모리 셀의 개수(바이트 수)를 알아야 한다.

🙄 : 그럼 식별자 컴퓨터는 한 번에 읽어 들여야 할 메모리 셀의 크기를 어떻게 알 수 있는가?

🙆‍♀️ : 심벌 테이블이요!

컴파일러 또는 인터프리터는 심벌 테이블이라고 부르는 자료 구조를 통해 식별자를 키로 바인딩된 값의 메모리 주소, 데이터 타입, 스코프 등을 관리한다.

🤦‍♂️ : 그래서 심벌 테이블이 뭐냐고?

컴파일러와 인터프리터 등의 프로그래밍 언어 처리 시스템에서 식별자를 관리하는 자료구조.

심벌 테이블은 각 식별자에 대해 이름과 해당 식별자가 사용되는 메모리 주소 또는 다른 정보를 매핑한다.

인터프리터는 식별자를 사용할 때 해당 식별자가 선언되었는지, 어떤 타입인지, 어느 범위에서 유효한지 등을 파악해야 한다. 이러한 정보는 실행 중인 프로그램에서 변수나 함수를 사용할 때 식별자가 가리키는 정확한 메모리 주소를 알고 있어야 하기 때문이다.

심벌 테이블은 이러한 정보를 저장하고 유지 관리하는 역할을 한다. 컴파일러 또는 인터프리터는 소스코드를 분석하면서 식별자를 발견하면 해당 식별자와 관련된 정보를 심벌 테이블에 추가하거나 참조한다.

→ 일반적으로 해시 테이블 또는 기타 효율적인 데이터 구조를 사용하여 구현됨

→ 언어마다 다름

🌈 그래서 요약하자면!

프로그래밍 언어 처리 시스템에서 식별자를 관리하고, 해당 식별자의 정보를 저장하고 유지 관리하는 자료구조. 이를 통해 변수와 함수 등의 식별자를 정확하게 해석하고 프로그램을 올바르게 처리할 수 있다.

🌷 동적 타입 언어와 정적 타입 언어

자바스크립트의 모든 값은 데이터 값을 가진다.

🤔 : 그렇다면 변수는 데이터 타입을 가질까?

정적 타입 언어는 변수의 타입을 변경할 수 없으며, 변수에 선언한 타입에 맞는 값만 할당할 수 있음

→ 컴파일 시점에 타입체크 진행

→ 선언한 데이터 타입에 맞는 값을 할당했는지 보는 검사임

→ 이 검사 통과 못하면 실행 자체를 막음

타입의 일관성을 강제함으로서 더욱 안정적인 코드의 구현을 통해 런타임에 발생하는 에러를 줄인다

c, c++, 자바, 코틀린, 고, 하스켈, 러스트 , 스칼라 등등…

동적 타입 언어는 변수의 타입을 변경할 수 있으며, 변수에 할당된 값의 타입에 따라 실행 시점에 타입이 결정된다.

→ 변수의 타입을 설정하지 않고 값을 할당할 수 있음

→ 실행 도중에 변수의 타입이 자주 변경될 수 있음

→ 이로 인해 버그 발생 가능성이 높아짐

정적 타입 언어와 달리, 실행 시점에 타입이 결정되므로 타입 에러가 발생하기 쉽다. 따라서 개발자는 변수의 타입을 주의깊게 관리하고, 코드를 작성할 때 타입 에러를 방지할 수 있는 방법을 찾아야 한다.

typeof 연산자는 연산자 뒤에 위치한 피연산자의 데이터 타입을 문자열로 반환한다

var foo;
console.log (typeof foo);

foo = 3;
console.log (typeof foo);

이런식으로 실행할 수 있다.

자바스크립트의 변수에는 어떤 데이터 타입의 값이라도 자유롭게 할당할 수 있다

→ 값을 할당하는 시점에 변수의 타입이 동적으로 결정뙤고 변수의 타입을 언제든지 자유롭게 변경할 수 있다

💯  자바스립트의 변수는 선언이 아닌 할당에 의해 타입이 결정(타입 추론) 되며,
재할당에 의해 변수의  타입은 언제든지 동적으로 변할 수 있다.

이러한 특징을 동적 타이핑이라고 하며, 자바스크립트를 정적 타입 언어와 구별짓기 위해 동적 타입 언어라고 한다. 대표적인 동적 타입 언어로는 자바스크립트, 파이썬, PHP, 루비, 리스프 , 펄 등이 있다.

이쯤 되어 아까 했던 질문으로 돌아가 보자

🤔 : 그렇다면 변수는 데이터 타입을 가질까?

→ 기본적으로 변수는 타입을 갖지 않는다. 하지만 값은 타입을 갖는다.

따라서 현재 변수에 할당되어 있는 값에 의해 변수의 타입이 동적으로 결정된다고 표현하는 것이 더 적절하다.

변수는 값에 묶여 있는 값에 대한 별명이기 때문이다.

🌷 동적 타입 언어와 정적 타입 언어

동적 타입 언어는 변수에 어떤 값이라도 자유롭게 할당할 수 있다.

자바스크립트를 사용하다 보면 따로 변수 할당을 안 해줘도 원하는 타입으로 사용할 수 있기 때문에 이는 데이터 타입에 무감각해질 정도로 편리해진다.

그렇지만 편리함에 이면에는 위험도 있다.

모든 소프트웨어 아키텍쳐에는 트레이드오프가 존재하며, 모든 애플리케이션에 적합한 은 탄환은 없듯이 동적 타입 언어 또한 구조적인 단점이 있다

Trade-off = 두 개의 정책이나 목표 중 하나를 달성하고자 하면 다른 목표의 달성이 늦어지거나 희생되는 모순적 관계를 의미함.

은 탄환: 아마 고질적인 문제를 단번에 해결할 수 있는 명쾌한 해결책…정도를 의미한듯

변수 값은 언제든지 변경될 수 있기 때문에 복잡한 프로그램에서는 변화하는 변수 값을 추적하기 어려울 수 있다. 변수의 타입이 고정되어 있지 않고 동적으로 변한다.

→ 동적 타입 언어의 변수는 값의 변경에 의해 타입도 언제든지 변경될 수 있다.

  💯 따라서 **동적 타입 언어의 변수는 값을 확인하기 전**에는 타입을 확신할 수 없다.

개발자의 의도와는 상관없어 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되기도 한다.

잘못된 예측에 의해 오류를 뿜어내는 프로그램을 본다면… 🤦‍♀️

결국 동적 타입 언어는 유연성은 높지만 신뢰성은 떨어진다

🙋‍♀️ 안정적인 프로그램을 만들고 싶어요!

  • 변수는 꼭 필요한 경우에 한해 제한적으로 사용한다
  • 변수의 유효 범위는 최대한 좁게 만들어 변수의 부작용을 억제해야 한다
  • 전역 변수는 최대한 사용하지 않도록 한다
  • 변수보다는 상수를 사용해 값의 변경을 억제한다
  • 변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다.

사실 변수 오류는 그닥 많이 겪어보지 않았다. 내가 초보 개발자이며 아직 경험이 많이 없어서 그런지는 모른다. 하지만 책을 공부하다가 한번쯤은 정리해놓고 싶은 부분이라 작성해보았다.

728x90
300x250

+ Recent posts