[JS] 2. 변수 (Variable) & 객체 (Object)
Data영역에는null,undefined, 그리고 평가 단계에서의 변수 주소 (8bit)Stack영역에는 크기가 변할 수 없는 변수의 값이 저장 -> 원시 타입Heap영역에는 크키가 변할 수 있는 변수의 값이 저장 -> 객체 타입
변수 (Variable) : 하나의 값을 저장할 수 있는 메모리 공간
변수 = 선언 + 식별자 + 타입 + 값 + 소코프
- 자바스크립트는 개발자가 메모리 주소를 통해 값에 직접 접근하는 메모리 제어를 허용하지 않음
- 변수 이름을 어떤 값을 구별해 식별 가능한 고유한 이름이란 의미에서, 식별자 (
Identifier) 라고도 함- 식별자는 값이 아닌 메모리 주소를 기억하고 있어, 식별자로 메모리 공간에 저장된 값에 접근
var userId = 1;
var userName = 'John';
var user = { id: 1, name: 'John' };
var users = {
{ id: 1, name: 'John' }
}
- 변수 선언 (
variable declaration)을 통해 변수를 생성 →var,let,const키워드- 변수에 값을 할당하지 않았으면, 자바스크립트 엔진에 의해
undefined값이 할당되어 초기화 - 선언하지 않은 식별자에 접근하면 참조 에러 (
ReferenceError)가 발생
- 변수에 값을 할당하지 않았으면, 자바스크립트 엔진에 의해
리터럴 (literal) : 사람이 이해할 수 있는 문자나 기호를 통해 값을 생성하는 표기법
- 값 (
value) : 표현식이 평가되어 생성된 결과
10 + 20; // 30
- 표현식 (
expression) : 값으로 평가될 수 있는 구문- 구문 (
statement) : 프로그램을 이루는 기본 단위이자 최소 실행 단위 (선언문, 할당문, 조건문, 반복문 등)- 토큰 (
token) : 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소
- 토큰 (
- 구문 (
데이터 타입 (Date Type) : 값의 종류
- 숫자 타입 : 정수 및 실수를 모두 포함하는 타입으로 존재 (모든 수를 실수로 처리)
→ 큰 수를 위한BigInt타입과는 다름! (BigInt는 객체 타입으로, 모든 수를 정수로 처리) - 문자열 타입 : ‘’, “”, ``로 문자열을 감싼 텍스트 데이터
- 템플릿 (
template) 리터럴 :로 감싼 문자열 (ES6``부터 도입)- 멀티라인 문자열 : 백슬레시 (
\n) 없이 개행 가능 - 표현식 삽입 :
+으로${}로 감싼 표현식을 문자열로 변환해 삽입할 수 있음
- 멀티라인 문자열 : 백슬레시 (
- 템플릿 (
- 불리언 타입 : 참 (
true)과 거짓 (false) → 제일 작은 값 (1bit) - 심볼 (
symbol) 타입 : 변경 불가능한 원시 타입 (다른 값과 중복되지 않는 유일무이한 값)Symbol함수를 호출해 생성되며, 값은 외부에 노출되지 않음 (var key = Symbol('key');)- 프로퍼티 값에 고유한 값을 저장하고 싶을 때 사용될 수 있음
undefined타입 : 변수 선언에 의해 확보된 메모리 공간은 쓰레기 값이 아닌undefined로 초기화null타입 : 변수에 값이 없다는 것을 의도적으로 명시 (intentional absence)하기 위해 사용
객체 (Object) : 소프트웨어에서 속성과 기능을 가지는 프로그램의 단위
자바스크립트에서 원시 타입을 제외한 나머지 값들 (객체, 함수, 배열, 정규 표현식)은 객체 타입 (
Object Type)이다.→ 객체 타입은 프로퍼티 및 메소드를 모두 포함하고 있어, 상태와 동작을 하나의 단위로 구조화할 수 있다.
var person = {
name: 'John', // "name: 'John'"은 프로퍼티,
age: 21 // "name"은 프로퍼티 키, "'John'"은 프로퍼티 값
};
- 객체 타입은 변경 가능한 값 (
mutable) - 객체 타입을 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값 (
Reference value)에 접근 - 원시 타입과 다르게, 객체 타입은 여러 개의 식별자들이 하나의 객체를 공유할 수 있음
원시 타입과 객체 타입의 차이점? → 메모리 공간에 저장되는 위치에서 비롯된 차이!
- 원시 타입 (
Primitive) : 값이 스택 영역에 들어감 (Call-By-Value) (cf.변수의 주소는 별도로 관리됨)
→ (자바스크립트 엔진에 따라) 힙 영역 내의Symbol Table이나Constant Pool에 들어갈 수 있음 - 객체 타입 (
Object/Reference) : 값이 힙 영역에 들어감 (Call-By-Reference)
- 원시 값은 변경 불가능한 값 (
immutable)이지만, 객체 값은 변경 가능한 값 (mutable) - 원시 값을 변수에 할당하면 변수에는 실제 값이 저장되나, 객체를 변수에 할당하면 변수에는 참조 값이 저장
- 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달 (
Pass-By-Value)되나, 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달 (Pass-By-Reference)
변경 불가능하다는 것은 변수가 아니라 값에 대한 진술!
- 상수 (재할당이 금지된 변수) != 변경 불가능한 값 (읽기 전용 값)
- 처음 원시 값을 변수에 할당하면 실제 값이 저장되고, 값을 재할당하면 메모리 공간의 주소가 변경됨
→ 원시 값은 상태 변경을 금지해 불변성 (
Immutability)을 보장하여, 데이터의 신뢰성을 보장한다!
그러므로
Call-By-Value또한 엄격히 표현하면, 변수에 메모리 주소가 전달되는 것을 말한다!→ 식별자는 메모리에 저장된 값을 식별해야 하므로, 변수와 같은 식별자는 값이 아닌 메모리 주소를 기억한다.
Constant Poll : 스택 영역과 힙 영역 외에 리터럴을 저장하기 위해 자바스크립트 V8 엔진에서 도입
Integer가 저장되는 방식?Integer는 기본적으로 스택 영역의SMI(Small Integer)에 저장32/64Bit OS에서32/64Bit를 넘어서면 힙 영역의Constant Poll에 할당
String이 저장되는 방식?String은 문자열으로 취급 → 모든 리터럴은 힙 영역의Constant Poll에 할당
객체 리터럴에 의한 객체의 생성 : 중괄호 ({}) 내에 0개 이상의 프로퍼티를 정의
- 변수에 할당되는 시점에 자바스크립트 엔진이 객체 리터럴을 해석하여 객체를 생성
- 객체 리터럴의 중괄호는 코드 블록을 의미하지 않음 → 중괄호 뒤에 세미콜론을 붙이지 않음
var person = {
name: 'John',
sayHello: function() {
console.log('Hello');
}
}
프로퍼티 (property) : 객체의 상태를 나타내는 값 (data)
- 객체는 0개 이상의 프로퍼티의 집합 → 프로퍼티는 키 (
key)와 값 (value)으로 구성- 자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있다.
- 프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심볼 값 (
'',"", 식별자) - 프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값
var person = {
name: 'John'
}
- 마침표 프로퍼티 접근 연산자
.나 대괄호 프로퍼티 접근 연산자[]을 통해 프로퍼티 접근, 생성, 갱신, 삭제
// 프로퍼티 접근
console.log(person.name);
console.log(person[name]);
console.log(person[0]);
// 프로퍼티 갱신
person.name = 'Joo';
// 프로퍼티 동적 생성
person.age = 20;
// 프로퍼티 삭제
delete person.name;
ES6이후부터 객체 리터럴의 확장된 기능을 제공
// 프로퍼티 축약 표현
let name = 'Kim', age = 10;
const person = { name, age };
// 프로퍼티 이름으로 프로퍼티 키를 동적 생성
const prefix = 'person';
let i = 0 ;
const obj = {
[ ${prefix}-${++i} ] : i,
[ ${prefix}-${++i} ] : i,
[ ${prefix}-${++i} ] : i
};
// 메소드 축약 표현
const obj = {
name: 'Lee',
func() { console.log(this.name); }
};
자바스크립트
V8엔진은 자바스크립트 객체의 프로퍼티에 접근하기 위해 동적 탐색 (Dynamic Lookup) 방식 대신, 히든 클래스 (Hidden Class) 방식으로 사용자 편의성과 일정한 성능을 모두 보장하고자 함
메소드 (method) : 프로퍼티를 참조하고 조작할 수 있는 동작 (behavior)
- 일반 함수와 달리, 메소드는 객체에 묶어 있는 함수를 의미
- 자바스크립트의 함수는 일급 객체이므로, 값으로 취급할 수 있어 프로퍼티 값으로 사용할 수 있음
var person = {
name: 'John',
getName: function() {
return this.name;
}
}