들어가며

  • 최근 알고리즘을 풀며 hasOwnProperty 를 사용할 일이 있었다. hasOwnProperty는 말 그대로 프로퍼티를 갖고 있니? 하고 true와 false를 반환해주는 친구이다.
  • 클린코드 강의를 듣다 hasOwnProperty에 대한 설명이 또 나왔다. 내가 모르던 부분이 있길래 MDN에 들어가서 살펴보는데, hasOwnProperty 대신 hasOwn을 추천했다.
  • hasOwn을 추천하는 이유와 사용법에 대해 알아보게 됐다.

hasOwnProperty

//ex n = 0; control = "wsdawsdassw"

function controlNumber(n, control) {
  const controlKeys = [...control];
  const operation = {
    w: +1,
    s: -1,
    d: +10,
    a: -10,
  };
  // hasOwnProperty --> 지금은 불필요해보일 지 모르지만 
  // 추후 이상한 프로퍼티값이 들어오는 걸 방지해줄듯
  for (const controlKey of controlKeys) {
    if (operation.hasOwnProperty(controlKey)) {
      n += operation[controlKey];
    }
  }
  return n;
}

여기에서 hasOwnProperty의 역할은 보이는것과 같이, 정해지지 않은 프로퍼티 값이 들어오면 막아주는 역할을 한다.

이처럼 object.hasOwnPropery(property)를 통해 쉽게 그 프로퍼티가 있는지를 확인할 수 있었는데, 무엇이 문제일까?

아래의 예시를 보자.


hasOwnProperty의 문제점

const foo = {
  hasOwnProperty : function(){
    return "hasOwnProperty";
  },
  bar: 'Bar'
}
  • foo라는 객체는 hasOwnProperty라는 자신이 직접만든 함수를 가지고 있다.
  • 이를 기존의 hasOwnProperty 처럼 사용한다면?
console.log(foo.hasOwnProperty("bar")); // hasOwnProperty
  • true, false를 반환해주지 않고 정해놓은 값을 반환해버리고 만다.
  • 이를 어떻게 한담?

해결방법 1 - prototype

Object.prototype 의 hasOwnProperty로 가서 Object 것을 쓴다고 명시하고 사용하는 방법이다.

console.log(Object.prototype.hasOwnProperty.call(foo, 'bar')) // true
  • 이렇게 작성하면 직접 작성한 hasOwnProperty가 있어도 원래 사용하려했던 hasOwnProperty를 사용할 수 있다.

해결방법 2 - 직접 만들기

Object.prototype.hasOwnProperty.call 을 계속 작성하는것도 일이다. 이를 함수로 빼놓고 사용하는 방법이다.

function hasOwnProp(targetObj, targetProp){
  return Object.prototype.hasOwnProperty.call(targetObj, targetProp)
}

hasOwnProp(foo, 'bar') //true
  • 이렇게 작성하면 나중에 그냥 확인할 때 위 함수를 호출하면 되는 것이니 더 간단하게 느낄 수 있다.

hasOwn

  • 사실 위와 같은 문제를 대체하기 위해 hasOwnProperty를 대신해서 나온 것이 hasOwn이다.
  • 사용법은 아래와 같다.
const object1 = {
  prop: 'exists',
};

console.log(Object.hasOwn(object1, 'prop'));
// Expected output: true

console.log(Object.hasOwn(object1, 'toString'));
// Expected output: false
  • 아까 위에서 해결방법2 직접만들기와 비슷하게 사용할 수 있게 된다.

위의 hasOwnProperty의 문제를 hasOwn 으로 처리하게 된 것이다.

const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: "The dragons be out of office",
};

if (Object.hasOwn(foo, "bar")) {
  console.log(foo.bar); // true
}

그러면 맨 처음 예제로 봤던 알고리즘도 아래와 같이 바꿀 수 있다.

function solution(n, control) {
   const controlKeys = [...control]
   const operation = {
       'w' : +1,
       's' : -1,
       'd': +10,
       'a' : -10
   }
   for(const controlKey of controlKeys){
     //hasOwnProperty 대신 hasOwn
        if(Object.hasOwn(operation,controlKey)){ 
           n += operation[controlKey]
       }
   }
    return n
}

Tip

  • 자바스크립트에선 배열도 객체다. 객체에서 쓸 수 있는 hasOwn, hasOwnProperty도 배열에서 쓰일 수 있다. 다음과 같이 말이다.
const fruits = ["Apple", "Banana", "Watermelon", "Orange"];
Object.hasOwn(fruits, 3); // true ('Orange')
Object.hasOwn(fruits, 4); // false - not defined

결론

hasOwnProperty 대신 hasOwn을 쓰는게 맞나.. ?

마치며

  • 짧은 내용이지만 다시 되짚어보며 왜 되고 안되고를 확인해서 재미있는 경험이었다. 항상 더 나은 방법이 있는지 생각하게 해준 hasOwn 알아보기였다.

출처

profile
왜? 를 깊게 고민하고 해결하는 사람이 되고 싶은 개발자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN