Object 또한 빌트인 객체로, new 키워드를 사용해서 인스턴스를 만들 수 있다.
하지만, 모든 객체의 부모는 Object이기 때문에, 이미 Object의 instance다.
특이점은, new 키워드를 통해 데이터를 초기화하면, 데이터 타입에 따라 prototype으로 분리한다.
💡 prototype으로 분리된다는 것이지, 데이터 타입이 바뀐다는 것이 아님을 유의하자.
const arr = new Object([1, 2, 3]);
console.log(arr, typeof arr); // [Array]object
const num = new Object(1);
console.log(num, typeof num); // [Number]object
const bool = new Object(true);
console.log(bool, typeof bool); // [Boolean]object
Object.static.method
⚪ assign
기존 객체에 다른 객체의 key, value를 붙여 넣을 수 있다.
또한, 붙여넣은 결과를 반환한다.
assign은 얕은 복사이기 때문에, 원본데이터가 변경이 되더라도 대상객체와 retrun된 결과는 바뀌지 않는다.
그 순간의 데이터 값이 복사되었기 때문이다.
인자로는 (대상객체, 붙여넣을 객체들...) 을 전달한다.
const start = {
name: 'Nora',
age:22
};
const personal = {
hobby: 'dancing'
}
const school = {
major: 'English'
}
const person = Object.assign(start, personal, school);
console.log(start);
console.log(person);
personal.hobby = 'Art';
console.log(start); //연결x hobby: 'dancing'
console.log(person); // 연결x hobby: 'dancing'
⚪ keys, values, entries
object의 key, value, key+value를 배열 형태로 반환한다.
기존의 object가 이후에 변경되면, 업데이트 되지 않는다.
const obj = {x: 1, y: 2, z: 3};
const key = Object.keys(obj);
console.log(key); // ['x', 'y', 'z']
obj.o = 4;
console.log(key); // ['x', 'y', 'z']
console.log(obj); // {x: 1, y: 2, z: 3, o: 4}
key.push('g');
console.log(key); // ['x', 'y', 'z', 'g']
const value = Object.values(obj);
console.log(value); // [1, 2, 3, 4]
obj.t = 5;
console.log(value); // [1, 2, 3, 4]
console.log(obj); // {x: 1, y: 2, z: 3, o: 4, t: 5}
const entries = Object.entries(obj);
console.log(entries); // [['x',1 ], ['y', 2], ['z', 3], ['o', 4], ['t', 5]]
console.log(Object.getOwnPropertyDescriptor(Math,'PI'));
⚪ Object.preventExtentions()
객체의 프로퍼티를 추가하지 못하게 할 수 있다.
수정과 삭제는 가능하다.
Object.isExtensible() 메서드로 추가 가능 여부를 알 수 있다.
⚪ Object.seall()
객체의 프로퍼티를 추가, 삭제 하지 못하게 할 수 있다.
수정은 가능하다.
Object.isSealed() 메서드로 추가 삭제 가능 여부를 알 수 있다.
⚪ Object.freeze()
객체의 프로퍼티를 추가, 삭제, 수정 못하게 할 수 있다.
Object.isFrozen() 메서드로 추가, 삭제,수정 가능 여부를 알 수 있다.
❗얕은 동결이기 때문에 프로퍼티 내부의 값 은 변경이 가능하다.
⚪ Object.getOwnPropertyDescriptor()
객체의 프로퍼티의 속성값을 알 수 있다.
인자로는 해당 object와 알고자 하는 property를 전달한다.
⚪ Object.getOwnPropertyDescriptors()
객체의 전체 속성을 알 수 있다.
인자로는 object를 전달한다.
⭐ 알 수 있는 속성들 (데이터 프로퍼티, 접근자 프로퍼티 가능)
value: 값 (접근자프로퍼티는 get set으로 나옴)
writable: 수정여부 (접근자 프로퍼티는 없음)
enumberable: for in문, Object.keys 가능여부
configurable: 프로퍼티 삭제, value, writable 제외한 어트리뷰트 수정 여부
여기서 writable과 configurable의 차이가 와닿지 않아서 많이 찾아보았다.
writable은 value를 수정 할 수 있는 지에 대한 여부이다.
configurable는 value, writable을 제외한 enumerable, configurable을 수정 할 수 있는지에 대한 여부다.
따라서, JS의 빌트인 객체의 프로퍼티를 살펴보면 우리가 변경 할 수 없다.
attribute를 확인 해 보기 위해 Math의 PI를 조회 해 보았다.
console.log(Object.getOwnPropertyDescriptor(Math,'PI'));
{
value: 3.141592653589793,
writable: false,
enumerable: false,
configurable: false
}
console.log(Object.isFrozen('PI'));
true
이처럼, 프로퍼티를 추가, 삭제, 수정을 막는 메서드를 사용함으로써, 해당 attribute에 영향을 주는 것을 볼 수 있다.
하지만 프로퍼티를 전체적으로 영향을 주지 않고, 각 프로퍼티별로 영향을 줄 수 있는 메서드가 있다.
⚪ defineProperty
위에서 언급한, 전체 프로퍼티를 잠그는것이 아닌 각 프로퍼티의 attribute를 직접 설정하는 방법이다.
직접 설정하고 object를 확인 할 경우, 에디터에선 접근자 프로퍼티만 볼 수 있다.
에디터에 확인 할 경우, getOwnPropertyDescriptors를 통해 확인 할 수 있다.
브라우저에서는 확인이 가능하다.
인자는 (object, property, {attribute}) 로 작성한다.
초기 생성 할 때 생략하면 자동 false가 된다.
attribute생성 하지않고, 객체를 생성 할 경우는 자동 true가 된다.
const person = {};
Object.defineProperty(person, 'fullname', {
value: 'Nora',
writable: true
});
Object.defineProperty(person, 'name', {
get() {
return this.fullname
.split('')
.map((itm, idx) => idx=== 0 ? itm : '*')
.join('');
},
enumerable: true,
configurable: true
});
console.log(person); // getter, setter만 조회 가능
console.log(Object.getOwnPropertyDescriptors(person)); // 전체 확인 가능
const obj = new Object({x:1, y:2});
console.log(obj); //확인가능
console.log(Object.getOwnPropertyDescriptors(obj)); // 전체 확인 가능
⚪ defineProperties
attributes를 한번에 설정 할 수 있다.
인자로는 (object {property{attribute})로 작성한다.
에디터에서 object 조회시 getter, setter 함수만 가능하며, 에디터에서 확인 할 경우 getOwnPropertyDescriptors 메서드로 가능하다.
브라우저에서는 확인 할 수 있다.
Object.defineProperties(person, {
'fullname': {
value: 'Nora',
writable: true
},
'krAge': {
value: 20,
writable: true
},
'name':{
get() {
return this.fullname
.split('')
.map((itm, idx) => idx === 0 ? itm : '*')
.join('')
},
enumerable: true,
configurable: true
},
'age': {
set(age) {
this.krAge = age;
},
enumerable: true,
configurable: true
}
});
console.log(person);
person.age = 18;
console.log(person); // getter,setter만 조회 가능
console.log(Object.getOwnPropertyDescriptors(person)); // 전체 조회 가능