자바스크립트에서 모든 객체들은 Object 객체와 Object.prototype 객체의 모든 프로퍼티와 함수를 상속 받는다. 본 포스트에서는 대표적이면서도 자주 사용되는 객체 함수들을 소개해 본다.
Object.create()
Object.create(proto[, propertiesObject])
주어진 프로토타입(prototype)의 객체와 속성들을 갖고 있는 새 객체를 생성한다.
Object.assign()
하나 이상의 원본 객체들로부터 모든 열거 가능한 속성들을 대상 객체로 복사한다.
let user = {
name: 'Captain America',
age: 100
}
// 객체주소 참조 값이 복사되므로 서로 공유됨. 진정한 복사 X
let cloneUser = user;
// 빈 객체는 초기값, 내용을 그대로 복사함.
let cloneUser2 = Object.assign({}, user);
// job이라는 프로퍼티를 추가해서 객체 값을 얻음.
let cloneUser3 = Object.assign({}, user); // {job: 'hero', name: 'Captain America', age, 100}
// 같은 프로퍼티면 덮어씌워짐
let cloneUser4 = Object.assign({name: 'Iron Man'}, user); // {name: 'Iron Man', age, 100}
const userName = {name: 'Captain America'};
const userAge = {age: 100};
const userJob = {job: 'hero'};
// 객체 변수를 합칠 수 있음.
let cloneUser5 = Object.assign(userName, userAge, userJob);
Object.keys()
객체의 key만 담은 배열을 반환한다.
let user = {
name: 'Captain America',
age: 100,
job: 'hero'
};
Object.keys(user); // ['name', 'age', 'job']
Object.values()
객체의 값(value)만 담은 배열을 반환한다.
let user = {
name: 'Captain America',
age: 100,
job: 'hero'
};
Object.values(user); // ['Captain America', 100, 'hero']
Object.entries()
[key, value] 쌍을 담은 배열을 반환한다(객체→배열). 보통 객체를 2차원 배열로 변환하고 Map 자료형으로 만들 때 사용.
let user = {
name: 'Captain America',
age: 100,
job: 'hero'
};
Object.entries(user); // [['name', 'Captain America'], ['age', 100], ['job', 'hero']]
Object.fromEntries()
let userArr = [['name', 'Captain America'], ['age', 100], ['job', 'hero']];
Object.fromEntries(user); // {name: 'Captain America', age: 100, job: 'hero'}
2차원으로 구성된 [key, value] 형태의 배열을 객체로 반환한다(배열 → 객체).
Object.is()
두 값이 같은지 비교한다.
var obj = { a: 1 };
Object.is(obj, obj); // true
Object.is(null, null); // true
Object.is([], []); // false
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
Object.getPrototypeOf() / Object.setPrototypeOf()
해당 객체의 프로토타입을 반환(getPrototypeOf())하거나 프로토타입(내부의 [[Prototype]] 속성)을 설정(setPrototypeOf())한다.
Instanceof
해당 변수가 객체인지 비교하거나 객체가 특정 생성자의 자식인지 조회할 수 있다.
// Object객체랑 비교해서 객체 확인
child instanceof Object; // true
// 객체 상속 확인
child instanceof Parent; // true
child instanceof GrandParent; // true
delete
객체 내의 속성을 지울 수 있다. 성공 시 true를, 실패 시 false를 반환한다.
var obj = {
a: 'hi',
b: 'zero',
};
obj.b; // zero
delete obj.b;
obj.b; // undefined
hasOwnProperty()
특정 프로퍼티가 해당 객체에 존재하는지 검사한다. 해당 객체에서 직접 선언된 프로퍼티만 검사하며 같은 이름의 프로퍼티라 하더라도 상속 받은 프로퍼티는 false를 반환한다.
var obj = {
example: 'yes',
};
obj.example; // yes
obj.hasOwnProperty('example'); // true
obj.toString; // function toString() { [native code] }
obj.hasOwnProperty('toString'); // false
toString()
이 함수를 호출한 객체의 값을 문자열로 반환한다.
var arr = [10, "문자열", true]; // Array
var bool = false; // boolean
function func() { return 0; } // function
arr.toString(); // 10,문자열,true
bool.toString(); // false
func.toString(); // 함수의 소스 코드가 전부 문자열로 반환됨.
valueOf()
특정 객체의 원시 타입(primitive type)의 값을 반환한다. 자바스크립트에서는 원시 타입의 값이 기대되는 곳에 객체가 사용되면 내부적으로 이 함수를 호출하여 처리한다. 만약 어떤 객체가 원시 타입의 값을 가지고 있지 않다면 이 함수는 객체 자신을 반환한다.
function func(n) {
this.number = n;
}
myFunc = new func(4);
console.log(myFunc + 5); // A: [object Object]5
func.prototype.valueOf = function() { // valueOf() 메소드를 정의함.
return this.number;
}
console.log(myFunc + 5); // B: 9
위 예시에서 A 부분에서는 산술 연산을 위해 number 타입의 값이 기대되는 곳에 myFunc라는 객체가 사용된다. 따라서 자바스크립트는 내부적으로 해당 객체의 valueOf() 함수를 호출하여 처리하려 한다. 하지만 이 객체의 valueOf() 함수는 아직 정의되지 않았기 대문에 객체 자신을 반환하게 된다. 따라서 산술 연산이 아닌 문자열 결합 연산이 수행되는 것이다.
B 부분에서는 prototype 프로퍼티를 활용하여 valueOf() 함수를 정의한다. 따라서 내부적으로 호출된 valueOf()가 해당 객체의 number 프로퍼티 값을 반환하여 정상적으로 산술 연산이 수행되는 것이다.
Object.defineProperty() / Object.defineProperties()
객체의 속성을 자세히 정의할 수 있다.
writable: 속성값을 변경할 수 있는지 설정.
enumerable: for ... in 반복문 안에서 사용할 수 있는지 설정.
configurable: 속성의 설명을 바꿀 수 있는지 설정. false인 경우 delete 동작 또한 불가능함.
writable, enumerable, configurable 속성의 기본값은 false이며 value는 속성의 값, get은 속성의 값을 가져올 때, set은 속성의 값을 설정할 때 쓰인다.
var obj = {};
Object.defineProperties(obj, { // 객체 복수 정의
a: {
value: 5, // a: 5 로 설정
writable: false, // 쓰기 불가능
enumerable: true, // 순회 가능
},
b: {
get: function() { // defineProperties안에 get을 쓰면 getter로 동작
return 'zero';
},
set: function(value) { // defineProperties안에 set을 쓰면 setter로 동작
console.log(this, value);
this.a = value;
},
enumerable: false,
configurable: false,
},
});
obj.a; // 5
obj.b; // 'zero'
obj.a = 10;
obj.a; // writable이 false이므로 그대로 5
for (var key in obj) {
console.log(key); // b의 enumerable이 false이므로 a만 log됨
}
obj.b = 15; // 15로 설정되는 대신 set의 내용이 실행됨. set의 value는 15
obj.a; // this.a = value로 인해 15로 바뀌어야 하나 writable이 false이므로 무시됨
obj.b; // 그대로 'zero'
Object.defineProperty(obj, 'b', {
value: 5
}); // Uncaught TypeError: Cannot redefine property: b
Object.defineProperty(obj, 'b', { enumerable : true} ); // b의 순회가능함을 true로
'Javascript > Javascript' 카테고리의 다른 글
[Javascript] Event의 종류 (2) | 2024.10.15 |
---|---|
[Javascript] Array 함수 (0) | 2024.10.10 |
[Javascript] for ... in (0) | 2024.09.30 |
[Javascript] length 속성의 이해 (0) | 2024.09.30 |
[Javascript] for ... of (0) | 2024.09.27 |