자바스크립트 객체의 네이티브 메소드 중 하나다.
객체가 특정 프로퍼티를 가지고 있는지를 나타내는 boolean
값을 반환한다.
//예제1
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString'));
// expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false
//예제2
const obj = {
a: 1
};
obj.hasOwnProperty("a"); // true
obj.hasOwnProperty("b"); // false
단, 프로토타입 체인은 확인하지 않고, 해당 객체가 스스로 정의한 프로퍼티만을 판단한다.
obj.b = 2;
Object.prototype.c = 3;
obj.b; // 2
obj.c; // 3
obj.hasOwnProperty("b"); // true
obj.hasOwnProperty("c"); // false
const obj = {
a: 1,
b: 2,
c: 3
};
const copy = {};let sum = 0;
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
sum += copy[key] = obj[key] * 2;
}
}
sum => 2 + 4 + 6 = 12
위의 코드는 hasOwnProperty를 사용하지 않아도 오류가 발생하지는 않는다.
만약 사용하지 않는다면 다음과 같은 근거로 이유를 들 수 있다.
"나는 프로토타입 체인을 통해 추가적인 프로퍼티를 만들지 않았고, 추후에도 그럴 예정이 없다. 확실해!."
하지만 코드는 나중에 어떻게 수정될지 모르는 거고, 누군가 자신의 코드를 재사용하게될 수 있다.
하나의 예로 hasOwnProperty를 사용하지 않은 채, 시간이 흘러 누군가 코드를 수 정했다고 가정해보자.
Object.prototype.toText = function(){...}
Object의 프로토 타입에 toText라는 함수를 추가했다.
그렇다면, 원래의 코드의 결과는 어떻게 될 것인가?
for (let key in obj){
sum += copy[key] = obj[key] *2;
}
sum => NaN
sum의 결과는 NaN을 출력한다.
그 이유는 for...in 문법은 열거가능한 프로퍼티를 반복한다.
단, hasOwnProperty와 달리 프로토타입도 접근한다.
그렇기에 key를 출력해보면 다음과 같이 출력된다.
a
b
c
toText
겉으로는 안전해보이는 코드일지라도, 미래를 대비하지 못하는 코드다.
즉, 코드의 실행 환경 또는 prototype 접근 및 확장 여부와 같은 것들을 스스로 가정하면 안된다.
const me = {
firstName: "Lee",
lastName: "JungHyun"
};
let text = "The author name is ";
//원하는 결과 => The author name is LeeJungHyun
예제는 변수 text와 객체 me의 프로퍼티 값들을 합친 결과를 얻고 싶다고 가정하자.
이를 위해 다음과 같이 코드를 추가할 수 있다.
const me = {
firstName: "Lee",
lastName: "JungHyun",
toText() {
return this.firstName + this.lastName;
}
};
text + me.toText();
조금 더 간결하게 표현하면, 시스템적으로 암시적 호출되는 toString()을 활용할 수 있다.
즉, toString()을 오버라이딩해서 사용할 수 있다.
const me = {
firstName: "Lee",
lastName: "JungHyun",
toString() {
return this.firstName + this.lastName;
}
};
let text = "The author name is ";
text + me; // The author name is LeeJungHyun
위와 같은 코드가 존재할 때, toString()을 오버라이딩 했다는 것을 코드를 통해 명시적으로 알려주는 것이 좋다.
if (me.toString) {
text += me;
}
위와 같이 조건을 줄 수 있겠지만, 명확하지는 않다.
왜냐하면 me객체에 toString() 여부와 상관없이 프로토타입 체인을 통해 접근하기 떄문이다.
const me = {
firstName: "Lee",
lastName: "JungHyun",
toString() {
return this.firstName + this.lastName;
}
};
let text = "The author name is ";
// Bad - 프로토타입 체인을 통해 Object.toString 접근
if (me.toString) {
text += me;
}
// Good - 직접 정의 or 오버라이딩한 프로퍼티가 있는지 확인
if (me.hasOwnProperty("toString")) {
text += me;
}
이와 같이 hasOwnProperty를 사용함으로써, 많은 의미를 담을 수 있게 된다.
결과적으로 hasOwnProperty를 사용하는 이유는 크게 2가지로 나타낼 수 있다.
- 예상하지 못한 상황에 따른 버그 대비
- 코드의 가독성 향상.