본문 바로가기
Javascript

JavaScript - Primitive Type

by Su1993 2020. 9. 6.
반응형

자바스크립트에서는 원시 타입(Primitive Type)참조 타입(Reference Type)이라는 두 가지 자료형을 제공한다.


Primitive type(원시 타입)

원시 타입은 자바스크립트에서 객체가 아닌 것들이며 값 자체로 저장된 것이라 볼 수 있다.(원시타입은 value로 저장, 객체들은 reference로 저장) 즉, 원시타입의 데이터는 변수에 할당이 될 때 메모리 상에 고정된 크기로 저장되고, 해당 변수가 원시 데이터 값을 보관한다. 원시 타입 자료형은 모두 변수 선언, 초기화, 할당 시 값이 저장된 메모리 영역에 직접적으로 접근한다. 변수에 새 값이 할당될 경우, 실제로 변수에 할당되었던 원시타입의 값이 바뀌는 것이 아니라 새로운 원시타입의 값이 들어가는 개념이다. 원시타입 값 자체는 절대 바뀔 수 없다.(원시 타입은 불변적이다.)

 

Primitive type 종류

  • Boolean
  • String
  • Number
  • Undefined
  • Null
  • Symbol

Boolean

논리적인 요소를 나타내고, true와 false의 두 가지 값을 가질 수 있다.

String

텍스트 데이터를 나타내는 데 사용한다. 16비트 부호 없는 정수 값 요소들의 집합이다.

Number

두 배의 정밀함을 가진 64-bit float이다. 자바스크립트에는 정수만을 표현하기 위한 특별한 자료형은 없다. 부동 소수점을 표현할 수 있는 것 말고도, Number 타입은 +무한대, -무한대, NaN(숫자가 아님)이 있다.

Undefined

선언한 후 값을 할당하지 않은 변수 혹은 값이 주어지지 않은 인수에는 자동적으로 undefined 값이 할당된다.

Null

어떤 값이 의도적으로 비어있음을 표현하며 Boolean 연산에서는 false로 취급한다.

Symbol

ECMAScript 6에서 추가되었다. Symbol은 유일하고 변경 불가능한(immutable) 기본값이다. 또한, 객체 속성의 key값으로도 사용될 수 있다. 몇몇 프로그래밍 언어에서는 Symbol을 atom이라 부른다.

 


Reference type(참조 타입)

객체, 배열, 함수 등과 같은 Object 형식의 타입이며, 메모리에 값을 주소로 저장하고, 출력 시 메모리 주소와 일치하는 값을 출력한다.

 

함수

함수는 특별한 프로퍼티들을 가진 새로운 형태의 객체이다.

const a = function (exam) {};
a.name; // "a"
a.length; // 1

 

그리고 일반적인 객체와 같이 함수에 새로운 프로퍼티를 추가하는 것도 가능하다.

 

a.bar = "aa";
a.bar; // "aa";

 

함수는

  • 다른 함수의 인자 값으로 넘겨질 수 있다.
  • 변수나 데이터에 할당 가능하다.
  • 객체의 리턴 값으로 리턴 가능하다.

이러한 조건을 만족하기 때문에 함수를 1급 객체로 만들 수 있다. 이러한 특성은 자바스크립트의 객체들이 갖는 특성과 같다.

 

메소드

메소드는 함수와 같이 객체의 프로퍼티이다.

const c = {};
c.bar = function () { console.log("cc");};
c.bar(); // "cc"

 

 

생성자 함수

생성자 함수란 리턴 값으로 생성하는 함수를 객체 그 자체로서 반환하는 함수이다. 같은 코드를 공유하는 여러 가지 객체들을 갖고 싶을 때, 사용하면 유용하다. 생성자 함수는 다른 함수와 다른 점은 그저 new라는 키워드가 붙은 이후에 생성자 함수로서 사용된다는 점과 객체 자체를 리턴한다는 점밖에 없다. 그러므로 어떤 함수든 생성자 함수가 될 수 있다.

 

const a = function () {};
const b = new a();
b; // {}
b instanceof a; // true
b instanceof object; // true

 

생성자 함수는 object를 리턴하게 된다. object에 새로운 프로퍼티를 할당하기 위해 this를 함수 안에 사용할 수 있다. 예를 들어 "test" 값으로 초기화된 a라는 프로퍼티를 가진 object를 많이 만들고 싶다면 그 로직을 캡슐화하는 b라는 생성자 함수를 만들면 된다.

 

const b = function() {
	this.a = "test";
};
const c = new b();
c; // { a: "test" }
c instanceof b; // true
c instanceof object; // true

 

새로운 object를 만들기 위해서 생성자 함수를 사용할 수 있다.

 

new 키워드 없이 b()라는 함수를 실행하면 b는 일반적인 함수처럼 동작하게 된다. 그리고 위의 함수 내부의 this는 '실행 컨텍스트(Execution Context)'와 응답을 주고 받는다. 그래서 만일 b()라는 함수를 전역 컨텍스트에서 실행시키게 되면, 전역 컨텍스트 시점의 this인 window 객체에 a라는 프로퍼티가 추가된다.

 

b(); // undefined
window.a; // "test"

 

반대로 말하면, 일반 함수를 생성자 함수로 실행한다면 함수의 역할을 하기보다 그저 새로운 함수 object를 반환할 뿐인 것이다.

 

const color = new String("blue")
// color는 원시 타입의 "blue" 값을 갖는 것이 아니라 생성자 함수로 생성된 String 객체를 갖게 된다.

 

Wrapper Object(래퍼 오브젝트)

Boolean, String, Number, Function과 같은 원시 타입을 new 키워드로 생성하면 원시 타입에 대한 래퍼 오브젝트가 생성된다.

String은 문자열이 인자로 들어왔을 때, 원시 문자열(Primitive String)을 생성하는 전역 함수이다. String은 인자로 들어온 값을 문자열로 바꾸려 한다.

 

String(1234); // "1234"
String(true); // "true"
String(undefined); // "undefined"
String(null); // "null"
String(); // ""
String("blue") === "blue"; // "true"
typeof String("blue"); // "string"

 

new 키워드를 붙인다면 String은 생성자 함수로도 쓰일 수 있다.

 

const color = new String("blue");
typeof color; // "object"
color === "blue"; // false

 

그리고 위 생성자는 래퍼 오브젝트라고 불리는 새로운 Object를 만든다. 위 코드에서 새로운 Object는 "blue"라는 문자열을 다음과 같은 프로퍼티로 나타낸다.

 

{
    0: "b",
    1: "l",
    2: "u",
    3: "e",
    length: 4
}

 

래퍼 오브젝트는 오브젝트 래퍼(Object Wrappers)라는 이름으로도 자주 불린다.

 

Auto-Boxing(오토 박싱)

원시 타입 문자열 생성자와 일반 오브젝트 생성자 둘 다 String 함수를 이용한다. 그리고 원시 문자열 타입에서. constructor을 이용하여 생성자 프로퍼티를 확인할 수 있다.

 

const color = new String("blue");
color.constructor === String; // true
String("blue").constructor === String; // true

 

특정한 원시 타입에서 프로퍼티나 메소드를 호출하려 할 때, 자바스크립트는 처음으로 이것을 임시 래퍼 오브젝트로 바꾼 뒤에 프로퍼티나 메소드에 접근하려 한다. 이 과정에서 원본에는 아무런 영향을 미치지 않는다.

 

const a = "aa";
a.length; //2
a === "aa"; // true

 

위 예에서 length 프로퍼티에 접근하기 위해 자바스크립트는 a를 오토 박싱 하고 래퍼 오브젝트에 넣는다. 그리고 래퍼 오브젝트의 length 프로퍼티에 접근하고 값을 이용한 뒤에는 지워버린다. 이 모든 과정은 a라는 원시 타입 변수에 영향을 미치지 않는다. a는 그저 원시 타입 문자열일 뿐이다. 이러한 과정은 원시 타입에 프로퍼티를 할당하려고 할 때 자바스크립트가 왜 경고나 에러 메시지를 출력하지 않는지를 알려준다. 프로퍼티를 할당할 때 잠시 원시 타입을 이용한 래퍼 오브젝트를 만들고 거기에 할당하기 때문이다.

 

const a = 1;
a.bar = "test"; // Assignment done on temporary wrapper object
a.bar; // undefined

 

만일 undefined나 null과 같이 래퍼 오브젝트가 없는 원시 타입에 대해서 프로퍼티를 할당하려고 하면 자바스크립트는 에러메시지를 나타낸다.

 

const a = null;
a.bar = "test"; // Uncaught TypeError: Cannot set property 'test' of null
반응형

댓글