string,array,number와 같이 object라는 자료형이 있다.
//오브젝트
const food = {
name : 'hamburger',
price : 1500
}
//배열
const foods = ['hamburger','pasta','salad']
배열(array)을 예를 들어 설명하자면
1. 먼저 둘다 여러 값들이 들어 갈 수 있다.
2. 다만 배열은 특정한 특징을 정하고 그 안에 속하는 여러가지
데이터들이 존재하는 것이고,
- [ foods란 배열을 특징으로 삼고 그안에 속하는 'hamburger', 'pasta', 'salad' 들이 있다. ]
3. 오브젝트는 특정한 객체를 정하고 그 객체에 대해 '팔은 두개고 다리는 세개야' 라고 하는 것처럼 설명해준다고 보면 된다.
- [ food의 이름은 'hamburger' 이고 가격은 1500이야 ]
이 오브젝트에 접근하기 위해서는
console.log(food.name) // 'hamburger'
console.log(food.price) // 1500
' 오브젝트의 이름 뒤에 . 기호를 붙인 후 key( 속성명 )을 붙여주면 접근할 수 있다.
여기서 알아둘 점은 오브젝트엔 [ key ]과 [ value ] 이란 것이 있는데.
food 오브젝트의 [ name , price ] 처럼 각 값들의 id를 담당하는 부분이 [ key ]이고
그에 해당하는 [ 'hamburger' , 1500 ]과 같은 값들을 [ value ] 라고 한다.
※꿀팁
가끔 오브젝트를 다루다보면
오브젝트의 키로 호출할때
"나는 food 오브젝트의 key로 keyName 이란 변수에 담긴 값을 쓰고 싶어";
이 말이 뭐냐 더 자세히 설명하면
나는 food의 price를 호출할껀데
그냥 호출하는게 아닌 keyName이란 변수에 price문자를 담아서 호출하고싶다.
ex1) //그냥 호출하는것
food.price
ex2) //변수에 key이름을 담아 호출하는것
const keyName = 'price'
food.keyName
위의 ex2)와 같은 식으로 사용해야 할 때가 있다.
이름값을 받아온후, 그걸이용해서 오브젝트를 호출해야 할 때가..
그럴때 ex2) 처럼 사용해버리면 컴퓨터는
food의 'price'로 key를 잡는게 아니라
food의 'keyName'으로 key를 그냥 잡아버린다.
즉 keyname을 변수로 인식하지 못하고 string으로 인식해버린다.
이렇게 변수에 담긴 string을 이용해서 오브젝트의 key를 잡고 싶을땐
아래와 같이 사용해 주면 됨
food.keyName // x
food[keyName] // o
보유함수들
- assign
객체의 값을 복사한다.
유사 함수로는 "spread operator"가 있음
spread operator는 기존객체를 수정하지않지만,
assign은 기존객체를 수정할 수 있다.
let a = { name: 'a' }
let b = Object.assign({age:15},a)
a // { name: 'a' }
b // { name: 'a', age: 15 }
위 예시는 assign 사용시 인자 순서의 중요성을 보면 됨
Object.assign({age:15},a)
{age:15} 라는 리터럴 객체가 앞에 위치해있음
이는 {age:15} 라는 리터럴 객체에 추가로 a 객체를 덧붙이란 뜻임
그래서 a객체가 그대로 유지될 수 있음
let a = { name: 'a' }
let b = Object.assign(a,{age:15})
a // { name: 'a', age: 15 }
b // { name: 'a', age: 15 }
위 예시는 반대로 a인자가 앞에 위치하였고,
a 객체에 추가적인 리터럴 객체를 붙이는것이기 때문에
a와 b객체가 동일한 데이터를 지니게됨
spread operator는 위 문제를 신경쓸 이유가 없다.
주관적인 생각으론 assign을 굳이 쓸 이유가 없어보임
1.
let a = { name: 'a' }
let b = { age: 15, ...a }
2.
let a = { name: 'a' }
a = { ...a, age: 15 }
assign 함수를 이용해 데이터 복사문제를 생각하기보단
a를 이용하여 새로운 변수를 생성하고 싶다면 1 예시처럼
그냥 a에 추가 데이터를 넣고 싶다면 2예시처럼 사용하면 됨
- create
객체를 생성하며 "부여받을 프로토타입", "프로퍼티 설정" 을 한번에 할 수 있음
다만 사용도는 낮지않을까 생각함
let o = Object.create(Object.prototype,{
foo: { writable: true, configurable: true, value: "hello" }
});
인자로 상속받을 prototype과 상세한 속성스펙을 전달한다.
다만 보통의 경우에선 특별하게 prototype 상속을 기입한다거나,
속성스펙도 수정할 일이 적어 잘 사용하지 않을 것 같음
클래스나 프로토타입을 따로 만들어 상속하고
+ 속성스펙도 수정불가하게만든다거나 하는 설정이
동시에 들어가야하는게 아닌이상 쓰지 않을 것 같다..
- defineProperties
위의 create 함수 기능중 "프로토타입 설정" 을 제외한 함수
"프로퍼티 설정" 만을 상세하고 간편하게 할 수 있음
create보단 사용도가 높을듯
물론 "defineProperty" 함수를 통해 개별 프로퍼티만 설정이 가능하다.
const object1 = {};
let c = Object.defineProperties({}, {
property1: {
value: 42,
writable: true,
},
property2: {},
});
- entries
Object 객체의 "키,값" 정보를 배열로 반환해 주는 함수
const object1 = {
a: 'somestring',
b: 42,
};
let b = Object.entries(object1)
b // [["a",'somestring'],['b',42]]
이를 이용해 forEach, for of 등 반복문 수행이 수월해짐
예시1.
Object.entries(object1).forEach((e)=>{console.log(e)});
예시2.
for (const [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}
"Object.keys", "Object.values" 함수를 통해 키나 값만 배열로 받아올 수도 있음
- fromEntries
['key', 'value'] 유형의 배열객체를 Object.entries와 반대로 객체형태로 반환해 주는 함수
const cctv = [
{cctvCd:'01',name:'첫번째'},
{cctvCd:'02',name:'두번째'},
{cctvCd:'03',name:'세번째'}
]
위 배열을 재구성하여 새 객체를 생성함
fromEntries에 전달할 인자는 ["key", "value"] 배열로 구성되어야 함
(예시)
cctv 배열객체를 아래와 같이 수정하려한다.
{
01: {
cctvCd: '01',
name: '첫번째'
},
02: {
cctvCd: '02',
name: '두번째'
},
03: {
cctvCd: '03',
name: '세번째'
}
}
그러려면 [[01,{cctvCd: '01', name: '첫번째'}]] 처럼 인자 데이터 형식이 구성되어야함
let a = Object.fromEntries([
[01,{cctvCd: '01', name: '첫번째'}],
[02,{cctvCd: '02', name: '두번째'}],
[03,{cctvCd: '03', name: '세번째'}]
])
a // {
1: {cctvCd: '01', name: '첫번째' },
2: {...},
3: {...}
}
그런데 위 예시처럼 일일히 인자를 넣어주긴 귀찮으니
map함수와 같이 반복함수를 사용하여 콜백형태로 이용
Object.fromEntries(cctv.map((value) => [
value.cctvCd, value
]));
추가예시 (단순 형태변경이 아닌 추가 계산도 가능)
Object.fromEntries(cctv.map((value,i) => [
value.cctvCd + 3 , {...value, index:i}
]));
- freeze, seal, preventExtensions
ㄱ. freeze
객체동결기능 제공
defineProperty를 통해
writable과 configurable을 설정해 동결시킬 수 있지만,
freeze를 통해 간편하게 동결가능
Object.isFreeze 메서드를 통해 확인가능
let a = {age:15};
Object.freeze(a);
ㄴ. seal
freeze보다 약한동결
writable: true인 값에 한해 value만 변경 가능
객체의 구조자체만 유지하고싶다면 freeze보다 seal이 적당함
isSealed 메서드를 통해 확인가능
let a = {age:15};
Object.seal(a);
delete a.age; // error or 무변화
a.age = 13 // 정상작동
ㄷ. preventExtensions
삭제,수정 가능
단 확장 불가
isExtensible 메서드를 통해 확인가능
let a = {age:15};
Object.preventExtensions(a);
delete a.age; //
a // {}
a.age = 13;
a // {}
- groupBy
배열객체를 기준에 따라 그룹핑해줌
예시 1
const a = [1,2,3,4,5]
Object.groupBy(a,(c)=>{return c>3 ? 'small' : 'big'});
// {big: Array(3), small: Array(2)}
예시 2
const students = [
{ name: 'a', grade: 'A' },
{ name: 'b', grade: 'B' },
{ name: 'c', grade: 'A' },
{ name: 'd', grade: 'C' },
{ name: 'e', grade: 'B' }
];
Object.groupBy(students, (c) => {return c.grade});
// 위 결과는 아래와 같음
{
A: [
{
name: 'a',
grade: 'A'
},
{
name: 'c',
grade: 'A'}
],
B: [
{
name: 'b',
grade: 'B'
},
{
name: 'e',
grade: 'B'}
],
C: [
{
name: 'd',
grade: 'C'
},
]
}
- getOwnPropertyDescriptor
- getOwnPropertyDescriptors
- getOwnPropertyNames
프로퍼티의 정보를 가져옴
const a = {
name: 'a'
};
Object.getOwnPropertyDescriptor(a,'name') // value, writable, enumerable 등을 반환받음
// 첫번째 인자로 오브젝트, 두번째 인자로 프로퍼티명을 전달
Object.getOwnPropertyDescriptors(a) // {name:{value:'a',writable:true,...}, ...}
// 인자로 오브젝트를 전달
Object.getOwnPropertyNames(a) // ['name']
Object.keys(a) // ['name']
keys와 getOwnPropertyNames의 차이는 반환값 필터에 enumerable 값을 체크함
keys:
enumerable true인것만 반환
getOwnPropertyNames:
enumerable false것도 반환
Object.defineProperty(a,'test',{value:'test',enumerable:false})
Object.getOwnPropertyNames(a) // ['name','test']
Object.keys(a) // ['name']
- valueOf
- toString
valueOf는 객체의 원시값, toString은 객체의 문자열형태로 반환함
유사점은
valueOf는 객체의 비교시 자동으로 valueOf의 반환값을 이용해 비교하고,
toString은 +를 이용하여 다른 문자열과 연산시 자동으로 toString을 이용해 문자화한다.
비교시,연산시에는 객체의 값을 순수하게 반환하는데,
toStirng이나 valueOf 메소드를 재정의하여 상수값이나, 추가 계산이 첨부된 값을 반환하는것도 가능하다.
const a = {}
a.valueOf = () => 100;
a == 100 // true
- is
두 값이 같은 값인지 평가
==, ===와 다르다함
얼핏보기엔 ===와 유사
(일반적인상황에선 사용성이 높지않아보임)
+0, -0을 비교할때
===는 결국 같은값을 가리키고 있기때문에 true를 반환함
그러나 Object.is에서는 false를 반환함
이유는 명확하게 모르겠음
[],[] 를 인자로 주었을땐 '===' 와 같이 false를 반환함
'js > 개발' 카테고리의 다른 글
js Class (0) | 2024.10.15 |
---|---|
js 2진수, 8진수 사용하기 (0) | 2024.10.13 |
js Object Literal Syntax Extension (키 값 동적으로 생성) (0) | 2024.10.13 |
js rest parameters (0) | 2024.10.08 |
js async & await (0) | 2024.08.07 |
댓글