본문 바로가기

Languages/JavaScript

[JavaScript] hasOwnProperty를 쓰는 이유

728x90

 

hasOwnProperty를 써야하는 이유에 대해서 알아보자!

 

 


 

 

hasOwnProperty() 메서드객체가 특정 프로퍼티를 가지고 있는지를 나타내는 불리언 값(true/false)을 반환한다.
즉, 객체가 특정 프로퍼티를 가지고 있는지에 대한 소유 여부를 반환한다.

 

const obj = {
    a: 1
};
obj.hasOwnProperty("a"); // true
obj.hasOwnProperty("b"); // false

 

해당 객체에 특정 프로퍼티가 존재하면 true, 그렇지 않으면 false 를 반환한다.

단, 프로토타입 체인은 확인하지 않고, 해당 객체가 스스로 정의한 프로퍼티만을 판단한다.

 

obj.b = 2;  // 해당 객체가 스스로 정의한 프로퍼티
Object.prototype.c = 3;   // 프로토타입 체인

obj.b; // 2
obj.c; // 3

obj.hasOwnProperty("b"); // true
obj.hasOwnProperty("c"); // false

 

 

 

다른 예시로, for in 반복문 안에서 hasOwnProperty를 사용해보자.

아래 예시는 객체의 프로퍼티의 값을 2를 곱한 후, 새로운 객체(copy)에 할당하는 코드이다.

for...in 반복문에 대해 자세히 알고 싶다면, https://dev-ini.tistory.com/52 를 참고하세요! 

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;
  }
}

console.log(copy);  // {a: 2, b: 4, c: 6}

console.log(sum); // 12 (2+4+6)

 

위 예제에서는 왜 hasOwnProperty를 사용했을까?
사실 저것만 놓고 봤을 때는 안써도 무방하고, 오류도 발생하지 않는다.
하지만 사용하지 않을려면 전제가 필요하다.


"나는 프로토타입 체인을 통해 추가적인 프로퍼티를 만들지 않았고,  추후에도 그럴 예정이 없을 것이 확실하다!"

하지만 과연 이것을 100% 확신할 수 있을까?
협업을 생각하면, 언젠가 누군가가 코드를 재사용하거나 수정할 수도 있을 것이다.

만약 hasOwnProperty를 사용하지 않은 채, 시간이 흘러 누군가 코드를 수정했다고 가정해보자.
아래의 예시는 Object 의 프로토타입에 sayHello 라는 함수를 추가한 코드이다.

 

const obj = {
  a: 1,
  b: 2,
  c: 3
};
const copy = {};

let sum = 0;
for (let key in obj) {   // hasOwnProperty를 사용하지 않음
  sum += copy[key] = obj[key] * 2; 
}

Object.prototype.sayHello = function() {} // Object의 프로토타입에 sayHello라는 함수를 추가



console.log(copy); // {a: 2, b: 4, c: 6, sayHello: NaN}

console.log(Object.keys(copy));  // ['a', 'b', 'c', 'sayHello']

console.log(sum);  // NaN

 

for...in 반복문은 상속된 모든 열거 가능한 속성들을 반환한다.
즉, 모든 프로퍼티를 대상으로 순회하기 때문에, 해당 Object의 요소 뿐만 아니라 prototype chain으로 상속 받은 속성들도 함께 순회한다. 

따라서 위의 예시에서는 Object 의 프로토타입에 sayHello 라는 함수를 추가했고, 이 함수(값은 NaN)도 순회 대상에 포함되기 때문에, sum의 결과는 NaN 을 출력하는 것이다. ( 2+4+6+NaN=NaN )

결국  hasOwnProperty를 사용하지 않으면 미래를 대비하지 못하는 코드가 된다. 

따라서 코드의 실행 환경 또는 prototype 접근 및 확장 여부와 같은 것들을 스스로 가정하면 안될 것이다.
hasOwnProperty를 습관화해서 사용할 것을 권장한다.

 

 

참고자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

728x90