자바스크립트 데이터 타입
기본 타입(자체가 하나의 값)
숫자(Number)
- 모든 숫자를 64비트 부동 소수점 형태로 저장, 정수 실수 구분 없이 그 값을 바로 저장
// 숫자 타입
let intNum = 10;
let floatNum = 0.1;
// 문자열 타입
let singleQuoteStr = 'single quote string';
let doubleQuoteStr = "double quote string";
let singleChar = 'a';
// 불린 타입
let boolLet = true;
// undefined 타입
let emptyLet;
// null 타입
let nullLet = null;
console.log(
typeof intNum,
typeof floatNum,
typeof singleQuoteStr,
typeof doubleQuoteStr,
typeof singleChar,
typeof boolLet,
typeof emptyLet,
typeof nullLet,
);
=> number number string string string boolean undefined object
문자열(String)
- 문자열은 문자 배열처럼 인덱스를 이용해서 접근 가능
- 한 번 생성된 문자열은 읽기만 가능하지 수정은 불가능하다.
// str 문자열 생성
let str = 'test';
console.log(str[0], str[1], str[2], str[3]); // (출력값) t e s t
// 문자열의 첫 글자를 대문자로 변경?
str[0] = 'T';
console.log(str); // (출력값) test
불린값(Boolean)
undefined
- 값이 비어있음 -> 값이 할당되지 않은 변수, 변수 자체의 값 또한 undefined(타입이자, 값)
null
- 값이 비어있음 -> 개발자가 명시적으로 값이 비어있음을 나타내는 데 사용 (타입은 object)
let emptypLet;
let nullLet = null;
console.log(emptyLet); // undefined
console.log(nullLet); // null
console.log(typeof nullLet === null); // false
console.log(nullLet === null); // true
참조 타입(객체 타입) - 기본 타입을 제외한 모든 값은 객체
- 배열(Array)
- 함수(Function)
- 정규표현식
객체(Object) - '단순히 이름(key):값(value)'형태의 프로퍼티들을 저장하는 컨테이너, Hash 자료구조와 유사, 참조 타입인 객체는 여러 개의 프로퍼티들을 포함할 수 있으며, 이러한 객체의 프로퍼티는 기본 타입의 값을 포함하거나, 다른 객체를 가리킬 수도 있다. 이러한 프로퍼티의 성질에 따라 객체의 프로퍼티는 함수를 포함할 수 있으며, 자바스크립트에서는 이러한 프로퍼티를 메서드라고 부른다.
객체 생성
// Object() 생성자 함수를 통한 객체 생성
let foo = new Object();
// foo 객체 프로퍼티 생성
foo.name = 'foo';
foo.age = 30;
foo.gender = 'male';
console.log(typeof foo); // (출력값) object
console.log(foo); // (출력값) { name : 'foo', age: '30', gender: 'male' }
- 객체 리터럴 방식 이용 - 리터럴(표기법 -> 객체를 생성하는 표기법)
// 객체 리터럴 방식으로 foo 객체 생성
let loo = {
name: 'loo',
age: 20,
gender: 'female'
};
console.log(typeof loo); // (출력값) object
console.log(loo); // (출력값) { name: 'loo', age: 20, gender: 'female' }
// 생성자 함수
let Person = function (name) {
this.name = name;
};
// 생성자 함수를 통한 객체 생성
let voo = new Person('voo');
console.log(voo.name); // 출력값 voo
객체의 프로퍼티에 접근
// 객체 리터럴 방식을 통한 boo 객체 생성
let boo = {
name : 'boo',
major : 'computer science'
};
// 객체 프로퍼티 읽기
console.log(boo.name); // (출력값) boo
console.log(boo['name']); // (출력값) boo
console.log(boo.nickname); // (출력값) undefined
// 객체 프로퍼티 갱신
boo.major = 'electronics engineering';
console.log(boo.major); // (출력값) electronics engineering
console.log(boo['major']); // (출력값) electronics engineering
// 객체 프로퍼티 동적 생성
boo.age = 40;
console.log(boo.age); // (출력값) 40
// 대괄호 표기법만을 사용해야 할 경우
boo['full-name'] = 'bar boo';
console.log(boo['full-name']); // (출력값) bar boo
console.log(boo.full-name); // (출력값) NaN -> 수치 연산을 해서 정상적인 값을 얻지 못할 때 ('boo.full' - 'name'으로 인식해서 Not a Number가 나온다)
console.log(boo.full); // (출력값) undefined
객체의 프로퍼티 출력 (for in)
// 객체 리터럴을 통한 doo 객체 생성
let doo = {
name: 'doo',
age: 50,
major: 'computer science'
};
// for in 문을 이용한 객체 프로퍼티 출력
let prop;
for (prop in doo) {
console.log(prop, doo[prop]);
}
=> name doo
age 50
major computer science
객체의 프로퍼티 삭제 (delete) (객체의 프로퍼티를 삭제할 뿐, 객체 자체를 삭제하지는 못한다.)
// 객체 리터럴을 통한 roo 객체 생성
let roo = {
name: 'roo',
nickname: 'babo'
};
console.log(roo.nickname); // (출력값) babo
delete roo.nickname; // 프로퍼티 삭제
console.log(roo.nickname); // (출력값) undefined
delete roo; // 객체 삭제 시도
console.log(roo.name); // (출력값) roo
참조 타입의 특성 (객체의 모든 연산이 실제 값이 아닌 참조값으로 처리 -> 객체 자체를 저장하고 있는 것이 아니라 생성된 객체를 가리키는 참조값을 저장)
// 동일한 객체를 참조하는 두 변수 objA, objB
let objA = {
val: 40
};
let objB = objA;
console.log(objA.val); // (출력값) 40
console.log(objB.val); // (출력값) 40
objB.val = 50;
console.log(objA.val); // (출력값) 50
console.log(objB.val); // (출력값) 50
객체 비교 (동등 연산자 == 를 사용하여 두 객체를 비교할 때도 객체의 프로퍼티값이 아닌 참조값을 비교한다)
// 기본 타입과 참조 타입의 비교 연산
let a = 100;
let b = 100;
let objA = { value: 100 };
let objB = { value: 100 };
let objC = objB;
console.log(a == b); // (출력값) true
console.log(objA == objB); // (출력값) false
console.log(objB == objC); // (출력값) true
참조에 의한 함수 호출 방식
// Call by Value와 Call by Reference 차이
let a = 100;
let objA = { value: 100 };
function changeArg(num, obj) {
num = 200;
obj.value = 200;
console.log(num);
console.log(obj);
}
changeArg(a, objA);
console.log(a);
console.log(objA);
프로토타입
- 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있다. 마치 객체지향의 상속 개념과 같이 부모 객체의 프로퍼티를 마치 자신의 것처럼 쓸 수 있는 것 같은 특징이 있다.
- 자바스크립트에서는 이러한 부모 객체를 프로토타입 객체(짧게는 프로토타입)라고 부른다.
let protong = {
name: 'protong',
age: 99
};
console.log(protong.toString());
console.dir(protong);

- 객체 --proto--> Object.prototype
- 배열 --proto--> Array.prototype --proto--> Object.prototype
let emptyArray = []; // 배열 리터럴을 통한 빈 배열 생성
let emptyObj = {}; // 객체 리터럴을 통한 빈 객체 생성
console.dir(emptyArray.__proto__);
console.dir(emptyObj.__proto__);


- 배열도 자바스크립트의 객체이므로, 인덱스가 숫자인 배열 원소 이외에도 객체처럼 동적으로 프로퍼티를 추가할 수 있다.
// 배열의 동적 프로퍼티 생성
let arr = ['zero', 'one', 'two'];
console.log(arr.length); // (출력값) 3
// 프로퍼티 동적 추가
arr.color = 'blue';
arr.name = 'number_array';
console.log(arr.length); // (출력값) 3
// 배열 원소 추가
arr[3] = 'red';
console.log(arr.length); // (출력값) 4
// 배열 객체 출력
console.dir(arr);

- 배열의 length 프로퍼티는 배열 원소의 가장 큰 인덱스가 변했을 경우만 변경된다.