Christmas Pikachu JS 객체에 특정 속성이 있는지 확인하는 법
개발일지/자바스크립트

JS 객체에 특정 속성이 있는지 확인하는 법

ZI_CO 2024. 11. 13.

1. in 연산자 사용하기

자바스크립트에서 객체에 어떤 속성이 있는지 확인하는 가장 널리 알려진 방법은 in 연산자를 사용하는 것입니다. 이 연산자는 다음과 같은 형태로 사용합니다:

const obj = { a: 1 };
"a" in obj; // true  // 객체에 'a'라는 속성이 존재하므로 true 반환
"b" in obj; // false // 객체에 'b'라는 속성이 없으므로 false 반환

in 연산자는 객체에 해당 속성이 존재하면 true를, 존재하지 않으면 false를 반환합니다. 객체를 생성한 후에도 얼마든지 속성을 추가할 수 있기 때문에 in 연산자의 결과는 객체의 현재 상태에 따라 달라질 수 있습니다.

obj.b = 2;
"b" in obj; // true  // 'b' 속성을 추가했기 때문에 true 반환

null이나 undefined 값도 속성으로 판단

in 연산자는 속성에 할당된 값이 null이나 undefined여도 속성이 존재하면 true를 반환합니다

obj.a = null;
"a" in obj; // true  // 'a' 속성에 null 값이 있어도 속성이 존재하므로 true 반환

obj.a = undefined;
"a" in obj; // true  // 'a' 속성에 undefined 값이 있어도 속성이 존재하므로 true 반환

속성을 아예 삭제하려면 delete 연산자를 사용합니다

delete obj.a;
"a" in obj; // false  // 'a' 속성을 삭제했기 때문에 false 반환

상속된 속성도 포함

in 연산자는 상위 클래스로부터 상속받은 속성도 고려합니다. 예를 들어, 모든 객체는 Object 클래스로부터 toString과 같은 속성을 상속받습니다

const obj = { a: 1 };
"toString" in obj; // true  // 'toString'은 Object로부터 상속된 메서드이기 때문에 true 반환

클래스 상속에서도 마찬가지입니다:

class Person {
  constructor(name) {
    this.name = name;  // 'name' 속성 정의
  }

  getInfo() {
    return `Name: ${this.name}`;  // 'getInfo' 메서드 정의
  }
}

class Student extends Person {
  constructor(name, grade) {
    super(name);  // 부모 클래스의 생성자를 호출
    this.grade = grade;  // 'grade' 속성 정의
  }

  getGrade() {
    return `Name: ${this.name}, Grade: ${this.grade}`;  // 'getGrade' 메서드 정의
  }
}

const student = new Student("Dale", 1);
"getGrade" in student; // true  // Student 클래스에서 정의한 'getGrade' 속성이 존재하므로 true 반환
"getInfo" in student; // true  // Person 클래스로부터 상속받은 'getInfo' 속성이 존재하므로 true 반환
"toString" in student; // true  // Object 클래스로부터 상속받은 'toString' 속성이 존재하므로 true 반환

in 연산자는 객체에 직접 정의된 속성뿐만 아니라 상속된 속성도 true로 반환합니다.

2. Object.hasOwn() 메서드 사용하기

in 연산자는 상속된 속성도 포함하기 때문에 객체 자신의 속성만 확인하고 싶다면 Object.hasOwn() 메서드를 사용하는 것이 좋습니다. 이 메서드는 객체에 해당 속성이 직접적으로 존재하는지 확인할 수 있습니다

const obj = { a: 1 };
Object.hasOwn(obj, "a"); // true  // 'a'는 객체에 직접 정의된 속성이므로 true 반환
Object.hasOwn(obj, "toString"); // false  // 'toString'은 상속된 속성이므로 false 반환

이 메서드는 in 연산자와 달리 상속된 속성을 무시하고, 객체 자신의 속성만을 판단합니다.

3. Object.prototype.hasOwnProperty() 메서드

Object.hasOwn() 메서드가 등장하기 전에, 상속된 속성을 제외하고 객체 자신의 속성만 확인하기 위해 Object.prototype.hasOwnProperty() 메서드를 많이 사용했습니다

const obj = { a: 1 };
obj.hasOwnProperty("a"); // true  // 'a'는 객체에 직접 정의된 속성이므로 true 반환

하지만 이 메서드에는 몇 가지 문제가 있습니다. 예를 들어, 프로토타입이 없는 객체(null-prototype 객체)에서는 hasOwnProperty() 메서드를 사용할 수 없습니다

const obj = Object.create(null, { a: { value: 1 } });
obj.hasOwnProperty("a"); // TypeError: obj.hasOwnProperty is not a function  // 프로토타입이 없으므로 오류 발생

또한, 객체에 hasOwnProperty라는 이름의 속성을 추가하면 문제가 발생할 수 있습니다

const obj = { a: 1 };
obj.hasOwnProperty = () => true;  // 'hasOwnProperty' 속성을 덮어씀
obj.hasOwnProperty("b"); // true  // 실제로는 존재하지 않지만 덮어쓴 메서드로 인해 true 반환

이런 문제를 해결하기 위해 Object.hasOwn() 메서드를 사용하는 것이 권장됩니다.

4. 실전 예제: 특정 속성 확인하기

다음은 실전에서 자주 겪을 수 있는 예제입니다. abbreviations 객체에 약어와 그 의미를 저장하고, standFor() 함수로 약어의 의미를 반환하는 코드입니다:

const abbreviations = {
  HTML: "HyperText Markup Language",
  CSS: "Cascading Style Sheets",
  JS: "JavaScript",
};

function standFor(abbr) {
  // 약어가 객체에 존재하는지 확인
  if (abbr in abbreviations) {
    return abbreviations[abbr];  // 약어의 의미를 반환
  }
  throw new Error("Not found");  // 존재하지 않으면 오류 발생
}

standFor() 함수는 약어가 객체에 존재하면 그 의미를 반환합니다:

standFor("HTML"); // 'HyperText Markup Language'
standFor("CSS"); // 'Cascading Style Sheets'
standFor("TypeScript"); // Error: Not found  // 존재하지 않는 약어이므로 오류 발생

하지만 toString을 인자로 넘기면 예상치 못한 결과가 나옵니다:

standFor("toString"); // ƒ toString() { [native code] } 😵  // 상속된 'toString' 메서드를 반환

이 문제를 해결하려면 in 연산자 대신 Object.hasOwn()을 사용해야 합니다

function standFor(abbr) {
  // 약어가 객체 자신에 직접 정의된 것인지 확인
  if (Object.hasOwn(abbreviations, abbr)) {
    return abbreviations[abbr];  // 약어의 의미를 반환
  }
  throw new Error("Not found");  // 존재하지 않으면 오류 발생
}

이제 toString을 인자로 넘겨도 올바르게 오류가 발생합니다

standFor("toString"); // Error: Not found  // 상속된 속성이므로 오류 발생

마무리하며

지금까지 자바스크립트에서 객체에 특정 속성이 존재하는지 확인하는 방법들을 살펴보았습니다. 간단히 정리하면

  • in 연산자: 객체 자신의 속성뿐만 아니라 상속된 속성까지 포함하여 존재 여부를 판단합니다.
  • Object.hasOwn() 메서드: 객체 자신이 직접 가진 속성만 확인할 수 있습니다.
  • Object.prototype.hasOwnProperty() 메서드: 기존에 많이 사용되었으나 몇 가지 문제가 있어 가급적 피하는 것이 좋습니다.

Object.hasOwn() 메서드는 최근에 등장하여 안전하고 명확하게 객체의 속성 존재 여부를 확인할 수 있으므로, 최신 환경에서는 이 메서드를 사용하는 것이 권장됩니다. 자바스크립트를 다룰 때 이 점을 유념해서 코드의 신뢰성을 높이세요!

댓글