JavaScript
Today I Learned ... javascript
🙋♂️ Reference Book
🙋 My Dev Blog
10. 객체 리터럴
- 자바스크립트는 객체기반 프로그래밍 언어로, 원시값을 제외한 모든 값이 모두 객체이다.
- 원시값은 단 하나의 값만 나타내지만, 객체 타입은 다양한 타입의 값을 하나의 단위로 구성한 복합적
자료구조
(data structure)이다.
프로퍼티 | 메서드 |
---|
객체의 상태 를 나타내는 data | 상태 data(=프로퍼티)를 참조, 조작하는 동작 |
객체 리터럴
- 자바스크립트는 프로토타입 기반 객체지향 언어로,
객체 리터럴 {}, 생성자함수, 클래스, Object.create() 등의 다양한 객체 생성 방법이 있다.
- 가장 간단한 방법은, 중괄호 {} 내에 프로퍼티를 정의하는
객체 리터럴
이다.
- 객체 생성 시기 = 변수가 할당되는 시점. (=연산자, 즉 런타임에 생성)
- 객체리터럴의 중괄호는 코드블록이 아니므로 세미콜론을 붙여줘야 한다.
프로퍼티(Property)
- 키(key) - 값(value)로 구성되며, 쉼표로 구분함.
- 프로퍼티 키로는 문자열 또는 Symbol값이 올 수 있다.
- 프로퍼티 값으로는 모든 값이 올 수 있다. (함수도 가능)
- 유효한 네이밍 규칙인 경우, 프로퍼티 키에 따옴표("") 생략 가능.
-> 특수문자가 들어가거나, 숫자로 시작하거나 하면 반드시 ''로 묶어주고,
프로퍼티 키를 참조할 때에도 []로 참조해야 한다. = 대괄호 표기법
메서드(Method)
- 프로퍼티 값으로 함수를 할당한 경우, 이를 객체에 묶여있는 함수 즉
메서드
라고 부른다.
- 자바스크립트에서 유효한 네이밍 규칙인 경우, 마침표 표기법(.)과 대괄호 표기법([])모두 사용 가능!
- 대괄호 표기법에는 반드시 ''를 붙여줘야 하지만 (문자열이므로), 마침표 표기법은 생략해도 된다.
프로퍼티 생성 / 삭제
- 프로퍼티 (동적) 생성 -> 존재하지 않는 프로퍼티에 값 할당시
- 프로퍼티 삭제 ->
delete
키워드 사용
객체 리터럴의 (ES6) 확장 기능
1. 프로퍼티 축약 표현
- 프로퍼티 값 === 프로퍼티 키인 경우에, 값을 생략 가능.
var x = 1, y = 2;
var obj = { x, y }
2. 프로퍼티 키 동적 생성
- 프로퍼티 키를 동적으로 생성시, 이전에는 리터럴 외부에서 대괄호 표기법으로 해줬음.
- 이제는 리터럴 내부에서도 계산된 프로퍼티 키를 동적 생성 가능.
const str = 'prop';
let i = 0;
const obj = {
[`${str}-${++i}`]: i,
[`${str}-${++i}`]: i,
[`${str}-${++i}`]: i,
}
3. 메서드 축약 표현 (=ES6 메서드)
const obj = {
sayHi : function() {
},
sayHello() {
}
}
ES6 메서드
- 자신을 바인딩한 객체인 [[HomeObject]]를 가짐 (
super
키워드 사용 가능)
- non-constructor이라서 생성자함수로 호출할 수 없음.
11. 원시값 vs 객체타입
원시 타입 vs 객체 타입
원시 타입 | 객체 타입 |
---|
변경 불가능한 값(immutable) | 변경 가능한 값(mutable) |
변경불가. 재할당을 통해 새로운 값으로 교체는 가능. | 변경 가능. |
변수에 할당시, 실제 값이 저장 | 변수에 할당시, 참조값이 저장 |
다른 변수에 할당시, 원시값이 복사되어 전달 | 원본의 참조값이 복사되어 전달 |
불변성
- 문자열은 1글자당 2Byte, 숫자는 8Byte의 메모리를 차지한다.
- 문자열은 유사 배열 객체(+ 이터러블)이기 때문에 각 문자에 접근 가능
-> 래퍼 객체 (원시값을 객체처럼 사용시 원시값을 감싸는 객체)
var str = 'hello';
str[0] = 'H';
console.log(str);
- 즉, 문자열의 일부 문자는 변경 불가능하지만,
새로운 문자열을 할당(=재할당)은 가능.
값에 의한 전달 (pass by value)
- 원시값은 다른 변수에 할당후 변경시, 원본과는 전혀 무관하다.
- 복사시 원시값이 복사되어 전달되기 때문에,
원본과 copy 변수는 다른 메모리 공간에 저장된 별개의 값이다.
참고로, 원시값은 비교시(===) 값만 비교한다.
원본과 copy의 값이 같다면 (original=copy=50), 둘은 같은 값이다. (메모리 주소는 다르지만)
객체타입의 변경가능
- 객체는 프로퍼티 개수가 동적으로 추가되고, 삭제되므로 메모리 공간의 크기를 사전에 정해둘 수 없다.
- 자바스크립트의 객체는 프로퍼티 키를 인덱스로 사용하는
해시테이블
이다.
-> 클래스 없이 객체를 생성할 수 있고, 생성 이후에도 프로퍼티 동적 생성이 가능.
- 참조값 = 생성된 객체가 저장된 메모리 공간의 주소, 그 자체.
- 변수가 값을 갖는 것이 아닌, 변수가 객체를 참조하고 있다(=가리키고 있다)고 표현.
- 원시값은 불변성을 띄므로, 값을 변경하려면 재할당밖에 방법이 없다.
- BUT. 객체는 재할당 없이 직접 변경 가능 (= mutable)
- 객체를 변경할때마다 복사해서 새롭게 생성시 - 복사(deep copy)시 비용이 많이 든다.
- ❗️주의 - 여러개의 식별자가 하나의 객체를 공유할 수 있음.
📌 깊은 복사 vs 얕은 복사
- 얕은 복사 : 한단계까지만 복사 (중첩된 객체는 참조만 복사) -> spread(...)
- 깊은 복사 : 중첩된 객체까지 모두 복사 -> _.cloneDeep()
-> 둘다 원본과 copy는 ref가 다른 별개의 객체임
참고로, 객체는 비교시(===) 두 객체의 참조값(ref)을 비교한다.
참조에 의한 전달 (pass by ref)
var obj = {
name: 'lee'
}
var copy = obj;
위 코드에서 obj와 person 자체의 ref는 달라도,
내부에서 참조하는 ref는 한 객체를 가리킨다.
(즉, 메모리 주소는 다르지만 동일한 참조값을 가짐)
- 두개의 식별자(obj, copy)가 같은 객체를 참조함.
- 한쪽에서 객체를 변경 (프로퍼티 추가, 삭제)시 서로 영향 O.
✅ 복사 vs 같은 값
- 복사시 - 참조값이 동일하므로 ===는
true
var obj = {
name: 'lee'
}
var copy = obj;
obj === copy;
- 값이 같을 시 - 둘의 참조값은 다르므로 ===는
false
var obj = {
name: 'lee'
}
var same = {
name: 'lee'
}
obj === same;