JavaScript - hasOwnProperty에 대해서 알아보자🤓

jodbsgh·2022년 10월 28일
0

🙋"JavaScript"

목록 보기
9/13
post-thumbnail

hasOwnProperty란?

자바스크립트 객체의 네이티브 메소드 중 하나다.
객체가 특정 프로퍼티를 가지고 있는지를 나타내는 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

루프 안에서 hasOwnProperty를 사용하는 코드

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가지로 나타낼 수 있다.

  1. 예상하지 못한 상황에 따른 버그 대비
  2. 코드의 가독성 향상.
profile
어제 보다는 내일을, 내일 보다는 오늘을 🚀

0개의 댓글