객체 생성시 키(속성)과 값(value)이 둘을 쌍으로 이루는 말을 프로퍼티라고 정리할 수 있는데요. 이러한 프로퍼티의 유무를 확인하는 방법 또한 존재합니다. 대표적으로 in 연산자, property.hasOwnProperty, Reflext.has 등의 방법이 존재합니다.
가장 대표적인 객체 내 프로퍼티 확인 방법으로 특정 프로퍼티의 키가 객체 안에 존재하는지를 확인할 수 있는 방법입니다. 이 연산자를 통해 특정 프로퍼티가 객체에 들어있을 때 true를, 아닐 경우 false를 반환합니다.
이 연산자의 경우 사용자가 특정 객체 내의 프로퍼티를 알고 있는 경우나, 클라이언트 서버에서 받아온 정보들로 생성된 객체들의 예상되는 프로퍼티들을 예상하여 각 확인에 대한 조건을 기준으로 분기를 만들어내는 용도로 사용됩니다.
추가로 in 연산자를 사용할 경우 객체 내에 존재하는 프로퍼티 뿐만 아니라 차후 살펴볼 상속 받은 프로토타입에서의 프로퍼티까지 확인이 가능하다는 점을 알아두시면 좋습니다.
// 기본 객체 const person = { name : "Re_Go", age : 30 }; // 기본적인 in 사용법 console.log('name' in person); // -> true 반환 | person 객체에 name 프로퍼티가 존재하므로 true를 반환합니다. console.log('anotherName' in person); // -> false 반환 | person 객체에 anotherName 프로퍼티는 존재하지 않으므로 false를 반환합니다. console.log('toString' in person); // -> true 반환 | 다만 앞서 설명한 것처럼 객체가 상속 받은 프로퍼티들도 in 연산자로 확인이 가능하기 때문에 모든 객체들은 기본적으로 상속 받게되는 Object 프로토타입의 메서드까지 상속을 받으므로 toString 등의 메서드 또한 in 연산자로 검색이 가능합니다. // 간단한 함수 활용 예제 function checkingProperties() { //객체의 특정 프로퍼티가 존재하는지를 확인하는 간단한 함수 (삼항 연산자로 더 간단하게 구현 가능합니다.) if ('name' in person) { console.log(`프로퍼티 ${person.name} 가 확인되었습니다.`); }else{ console.log(`정보 확인 불가능`); }; console.log('age' in person ? `프로퍼티 ${person.age} 가 확인되었습니다.` : '정보 확인 불가능' ); }; checkingProperties(); // 해당 프로퍼티들을 확인하는 것도 가능합니다. // for-in 이용한 전체 프로퍼티 나열법 for(key in person) console.log(person[key]); // person의 모든 프로퍼티를 출력합니다.
ES6 부터 객체에 대한 접근성과 관리를 보다 쉽게하기 위한 Reflect 빌트인 객체가 도입되었으며, 이 Reflect 빌트인 객체의 의 has 메서드를 사용해 프로퍼티 유무 확인이 가능합니다. 이 메서드는 in 연산자와 동일하게 동작합니다.
const person = { name : "Re_Go", age : 30, } console.log(Relfect.has(person, 'name')) // person객체에서 name 프로퍼티를 가지고 있는지 확인하므로 true를 반환합니다.
추후 살펴볼 Object의 프로토타입 체인 상에 위치한 모든 객체들이 사용 가능한 Object 빌트인 객체의 메서드로 특정 프로퍼티가 해당 객체 고유의 프로퍼티인 경우에만 true를 반환하고, 그 이외에 상속 받은 프로토타입의 프로퍼티이거나 존재하지 않는 프로퍼티일 경우 false를 반환하므로 객체에만 존재하는 프로퍼티 확인시 유용한 기능입니다.
const person = { name : "Re_Go", age : 30, } console.log(person.hasOwnProperty('name')); // person 객체에 대한 프로퍼티만 검색 후 true를 반환 console.log(person.hasOwnProperty('toString')); // 그러나 toString 프로퍼티는 직접적으로 가지고 있지 않기 때문에 false를 반환합니다. console.log(Object.getPrototypeOf(person).hasOwnProperty('toString'); // 만약 어떠한 객체가 특정 프로퍼티나 메서드를 상속받고 있는지를 확인하고 싶다면 in 연산자로도 확인이 가능하고, Object 빌트인 객체의 메서드 중 하나인 getPrototypeOf 메서드와 hasOwnProperty 조합으로 특정 객체가 상속 받고 있는(해당 객체의 프토토타입에 보관하고 있는) 특정 프로퍼티와 메서드를 검색하는 것 또 한 가능합니다.
for in을 사용할 경우 해당 객체가 가지고 있는 프로퍼티의 개수만큼 순회하며 키에 대한 값을 확인할 수 있게 됩니다.
또한 객체가 상속받는 프로퍼티 및 메서드의 검색도 가능하나, 이 경우 프로퍼티 어트리뷰트(프로퍼티의 설정값) 중 [[Enumerable]] 설정 상태가 ture(열거 가능) 상태인 프로퍼티만 검색이 가능한데,
기본적으로 상속 프로퍼티 및 메서드들은 이 [[Enumerable]] 속성이 false(열거 불가능) 이기 때문에 단순 검색인 in 연산자 에서는 검색이 가능하나 순회문인 for-in에서는 검색이 되지 않는다는 점과, 프로퍼티가 심볼로 지정된 경우에도 for in으로 검색 되지 않음을 주의해야 합니다.
const person = { name : "Re_Go", age : 30, marriage : false, } for(let key in person){ console.log(`${key} : ${person[key]}`) // 해당 person의 키들을 하나 하나 순회하면서 그에 대한 값(person[key]) 을 출력합니다. }
앞서 설명한 for in 루프를 통해 특정 객체의 프로퍼티를 확인하는 방법도 있지만, ES8 부터 추가된, Object 빌트인 객체의 메서드들인 keys(키 확인), values(값 확인), entries(키와 값을 포함한 전체 프로퍼티 확인)로 프로퍼티를 부분 또는 전체 확인이 가능합니다.
const person = { name : "Re_Go", age : 30, marriage : false, } console.log(Object.keys(person)); // 키인 name, age, marriage가 배열 안 문자열 형태로 반환됩니다. console.log(Object.values(person)); // 값인 "Re_Go", 30, false 값이 배열 안에서 각각의 고유 타입으로 반환됩니다. console.log(Object.entries(person)); // 키와 값을 포함한 프로퍼티가 이중 배열로 묶여서 반환됩니다.
특정 프로퍼티의 값이 null, 혹은 undefined인지를 확인하기 위한 접근법으로 ES11 이전까지 논리 연산자를 사용해 객체의 특정 프로퍼티의 값이 null인지 undefined인지를 확인해야 했는데, ES11에 도입된 이 옵셔널 체이닝(optional chaining)을 활용해 간단히 알아볼 수 있게 되었습니다.
이 옵셔널 체이닝은 연산자 ?.은 좌항의 연산자가 null, 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티나 값을 반환하는 구조입니다.
이 방법은 특정 프로퍼티가 null이거나 undefined일 경우 이에 대한 대응을 가능하게 하며, 연산 대상은 둘 이상도 가능합니다.
즉 비교 대상들을 ?. 마크로 이어 붙여 그 중 하나라도 null이나 undefined일 경우 undefined를 반환하고 그 뒤에 연산은 무시하기 때문에 단축 평가의 효과도 가지고 있으며, 이러한 이유로 이름 또한 옵셔널 체이닝(선택적 연결) 붙은 것이죠.
const person = { name : "Re_Go", age : 30, marriage : false, carLicense : undefined }; // 옵셔널 체이닝 이전 for(let key in person){ if(person[key] === null || person[key] === undefined) console.log(undefined); // 만약 객체의 특정 프로퍼티가 null이거나 undefined일 경우 undefined를 출력하게 합니다. else console.log(person[key]); // 그 반대의 경우, 데이터가 null이나 undefined가 아닐 경우 그 데이터를 그대로 출력합니다. }; //옵셔널 체이닝 이후 for (let key in person) { console.log(person[key]?.toString()); // 현재의 key의 값이 null이나 undefined일 경우 undefined를, 아닐 경우 현재 프로퍼티의 값들에 대한 toString메서드를 호출하여 그 값을 반환하게 됩니다. }