JavaScript의 Object
클래스의 정적 메서드이다.
정확하게는
hasOwnProperty()
: Object
의 프로토타입 메서드hasOwn()
: Object
의 정적 메서드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
객체에서는 예상치 못한 에러가 날 수 있음.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
null
, undefined
면 타입 에러in
연산자는 객체에 해당 키가 존재하는지만 확인한다. 자기 속성이든 상속 속성이든 모두 포함한다.
'key' in obj
구분 | hasOwnProperty() | Object.hasOwn() | 'key' in obj |
---|---|---|---|
정의 위치 | Object.prototype | Object 정적 메서드 | 연산자 |
상속된 속성 포함 여부 | ❌ | ❌ | ✅ |
안전성 | 제한적 | 매우 안전 | - |
권장 여부 | 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
등에 적용됩니다.hasOwnProperty
라는 속성을 덮어쓸(overwrite) 수도 있다.const obj = { hasOwnProperty: () => false };
obj.hasOwnProperty('key'); // ❌ 예상과 다르게 동작
Object.create(null)
로 생성된 객체는 Object.prototype
을 상속받지 않기 때문에, hasOwnProperty()
메서드 자체가 없다.const obj = Object.create(null);
obj.hasOwnProperty('key'); // ❌ TypeError
- 안전한 방식 사용
Object.prototype.hasOwnProperty.call(...)
if (Object.prototype.hasOwnProperty.call(obj, 'key')) {
// 안전하게 확인 가능
}
call
을 사용해 hasOwnProperty
를 명확히 Object.prototype
에서 호출한다.ESLint
경고가 발생하지 않는다.
- 최신 권장 방식
Object.hasOwn(...)
(ES2022 이상)
if (Object.hasOwn(obj, 'key')) {
// 가장 깔끔하고 안전한 방법
}
그래서 아래 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)) {
...
...
...
}
}