JavaScript : hasOwnProperty(), hasOwn()

NuyHes·2025년 6월 19일
0

[Study]

목록 보기
61/61
post-thumbnail

🕵️ hasOwnProperty() , hasOwn() 란?

JavaScript의 Object 클래스의 정적 메서드이다.
정확하게는

  • hasOwnProperty() : Object의 프로토타입 메서드
  • hasOwn() : Object의 정적 메서드

1. hasOwnProperty()

hasOwnProperty()Object.prototype에 정의된 인스턴스 메서드로 객체가 특정 속성을 자신의 속성으로 직접 가지고 있는지를 불리언 값을 반환한다.

📄 예시 코드

const object = {};
object.property1 = 42;

console.log(object.hasOwnProperty("property1"));
// Expected output: true

console.log(object.hasOwnProperty("toString"));
// Expected output: false

console.log(object.hasOwnProperty("hasOwnProperty"));
// Expected output: false

🚫 주의점

  • 객체가 hasOwnProperty라는 이름의 속성을 자체적으로 갖고 있다면 충돌 가능성 있음.
  • Object.create(null)로 만든 객체는 Object.prototype을 상속받지 않으므로 hasOwnProperty() 없음.
  • Proxy 객체에서는 예상치 못한 에러가 날 수 있음.

2. Object.hasOwn()

Object.hasOwn()은 ES2022(ES13)에서 도입된 정적 메서드hasOwnProperty()와 같은 기능을 더 안전하고 간단하게 제공한다.

📄 예시 코드

const object = {
  prop: "exists",
};

console.log(Object.hasOwn(object, "prop"));
// Expected output: true

console.log(Object.hasOwn(object, "toString"));
// Expected output: false

console.log(Object.hasOwn(object, "undeclaredPropertyValue"));
// Expected output: false

💡장점

  • 충돌 위험 없음
  • 프로토타입이 없는 객체도 안전하게 사용 가능
  • Proxy 객체에도 잘 작동
  • MDN 및 TC39에서 공식적으로 권장

🚫 주의점

  • 구버전 환경에서는 미지원 ES2022 이상
  • 첫 인자가 null, undefined면 타입 에러
  • TypeScript 4.9 버전 미만에서는 타입 정의가 없음

3. in 연산자 ('key' in obj)

in 연산자는 객체에 해당 키가 존재하는지만 확인한다. 자기 속성이든 상속 속성이든 모두 포함한다.

  • 단순히 속성이 있는지 여부만 빠르게 체크할 때 사용
  • 상속된 프로퍼티도 포함되므로 정확한 소유 여부 확인엔 부적합

📄 예시 코드

'key' in obj

🆚 비교표

구분hasOwnProperty()Object.hasOwn()'key' in obj
정의 위치Object.prototypeObject 정적 메서드연산자
상속된 속성 포함 여부
안전성제한적매우 안전-
권장 여부MDN기준 비권장권장조건부

📄 실제 예제

// vue3
const apiParams = reactive({
    selectDate: null,
    selectId  : null,
});

apiParams에 있는 값을 update하는 함수를 만들어야 한다. 매개 변수로 들어오는 값이 apiParams에 있는 속성인지 먼저 체크를 한 후 실행하는 함수인데 조건문을 만든다.

function updateApiParam (paramKey: string) {
	if (apiParams.hasOwnProperty(paramKey)) {
		...
		...
		...
	}
}

저렇게 사용하면 별 문제 없어보였는데 아래와 같은 ESlint 에러가 뜬다.

Do not access Object.prototype method 'hasOwnProperty' from target object.eslint[no-prototype-builtins](https://eslint.org/docs/latest/rules/no-prototype-builtins)

(method) Object.hasOwnProperty(v: PropertyKey): boolean

Determines whether an object has a property with the specified name.

_@param_ `v`A property name.

에러 메시지는 ESLint의 no-prototype-builtins 규칙에 의해 발생한 것이다.


no-prototype-builtins

  • 이 규칙은 obj.hasOwnProperty() 같은 Prototype 메서드 직접 호출을 막습니다.
  • hasOwnProperty, isPrototypeOf, propertyIsEnumerable 등에 적용됩니다.

  1. 어떤 객체는 hasOwnProperty라는 속성을 덮어쓸(overwrite) 수도 있다.
const obj = { hasOwnProperty: () => false };
obj.hasOwnProperty('key'); // ❌ 예상과 다르게 동작
  1. Object.create(null)로 생성된 객체는 Object.prototype상속받지 않기 때문에, hasOwnProperty() 메서드 자체가 없다.
const obj = Object.create(null);
obj.hasOwnProperty('key'); // ❌ TypeError

해결 방법

  1. 안전한 방식 사용 Object.prototype.hasOwnProperty.call(...)
if (Object.prototype.hasOwnProperty.call(obj, 'key')) {
  // 안전하게 확인 가능
}
  • call을 사용해 hasOwnProperty를 명확히 Object.prototype에서 호출한다.
  • ESLint 경고가 발생하지 않는다.
  • 모든 객체에 대해 안전하게 동작한다 (Proxy 포함).
  1. 최신 권장 방식 Object.hasOwn(...) (ES2022 이상)
if (Object.hasOwn(obj, 'key')) {
  // 가장 깔끔하고 안전한 방법
}
  • 최신 JS 환경에서 기본적으로 지원
  • MDN과 ESLint에서도 권장
  • 단, 구형 브라우저나 Node.js v16 미만에서는 지원되지 않을 수 있음

그래서 아래 3가지로 사용할 수 있다. 나는 내부 속성값만 찾으면 돼서 1번 조건문을 사용하거나 3번 조건문을 사용하려고 한다.

function updateApiParam (paramKey: string) {
	// 1️⃣ in 연산자 사용
	if ( paramKey in apiParams) {
		...
		...
		...
	}
	// 2️⃣ hasOwnProperty를 에러 없이 call을 사용해 안전하게 사용
	if (Object.prototype.hasOwnProperty.call(apiParams, paramKey)) {
		...
		...
		...
	}
	// 3️⃣ 최신 문법 안전하게 사용
    if (Object.hasOwn(apiParams, paramKey)) {
		...
		...
		...
    }
}

0개의 댓글