💡 JS에서는 객체에 특정 속성이 있는지 체크할 수 있는 방법이
in
,hasOwn
,hasOwnProperty
가 있다. 그런데, 이 메소드는 어떤 차이가 있길래 여러 개가 존재하는걸까? 이번시간에는 이 세 메소드의 차이에 대해 알아보았다.(차이점만 보고 싶다면, 바로 2.메소드 간 차이보기로 넘어가자)
1. 각 메소드 알아보기
1) in 연산자
in
연산자는 특정 속성이 해당 객체에 있는지 여부를 boolean으로 리턴해준다.
속성 in 객체
(1) array의 경우
- array에서
in
연산자를 사용하면, 인덱스에 대해서만 체크할 수 있다.
const arr = ['apple', 'orange', 'banana'];
console.log(0 in arr); // true
console.log((1+1) in arr); // true
console.log('apple' in arr); // false
(2) string의 경우
- string에서는
in
연산자를 사용하면 에러가 발생한다. - 하지만, new String로 선언하면 string에서 사용할 수 있는 속성(length)에 대해서 체크할 수 있다.
const text = new String('hello');
console.log('length' in text); // true
(3) object의 경우
- object에서
in
연산자를 사용하면, 해당 객체에 특정 속성이 있는지 체크할 수 있다.
const obj = {'a': 1, 'b': 2, 'c': 3};
console.log('a' in obj); // true
console.log(1 in obj); // false
(4) 상속된 속성
- JS에서는 객체를 생성하면 우리는 JS에서 제공하는 내장 메소드에 접근할 수 있다.
- 이는 JS의 프로토타입 체인 때문인데, 특이한 점은 이 체인으로 인해 객체의 내장 속성을 체크할 수 있다!
console.log('slice' in []); // true
2) hasOwnProperty
hasOwnProperty()
은 해당 객체에 특정 속성이 있는지 여부를 boolean으로 리턴해준다.
obj.hasOwnProperty(property)
(1) array의 경우
const arr = ['apple', 'orange', 'banana'];
console.log(arr.hasOwnProperty(1)); // true
console.log(arr.hasOwnProperty('apple')); // false
(2) string의 경우
- new 생성자를 이용해 String을 선언하면, length 속성이 있는지 체크할 수 있다.
const text = new String('hello');
console.log(text.hasOwnProperty('length')); // true
(3) object의 경우
const obj = {'a': 1, 'b': 2, 'c': 3};
console.log(obj.hasOwnProperty('a')); // true
console.log(obj.hasOwnProperty(1)); // false
(4) 상속된 속성
hasOwnProperty()
는 프로토타입 체인으로 인해 객체에서 기본 제공되는 속성에는 접근할 수 없다.
console.log([].hasOwnProperty('slice')); // false
3) Object.hasOwn()
- 기능은
hasOwnProperty()
와 유사하다.
Object.hasOwn(target, property);
(1) array의 경우
const arr = ['apple', 'orange', 'banana'];
console.log(Object.hasOwn(arr, 1)); // true
console.log(Object.hasOwn(arr, 'apple')); // false
(2) string의 경우
- new 생성자를 이용해 String을 선언하면, length 속성이 있는지 체크할 수 있다.
const text = new String('hello');
console.log(Object.hasOwn(text, 'length')); // true
(3) object의 경우
const obj = {'a': 1, 'b': 2, 'c': 3};
console.log(Object.hasOwn(obj, 'a')); // true
console.log(Object.hasOwn(obj, 1)); // false
(4) 상속된 속성
- 프로토타입 체인으로 인해 객체에서 기본 제공되는 속성에는 접근할 수 없다.
console.log(Object.hasOwn([], 'slice')); // false
2. 메소드 간 차이점 한 눈에 보기
1) 상속된 속성
- 프로토타입 체인으로 인해, 객체를 프로토타입 방식으로 선언하면 내장 함수를 사용할 수 있다.
- 그런데 객체의 속성을 체크할 때 이 내장 속성도 체크할 수 있는데,
in
연산자만 가능하다.
const cat = {
name: 'lala',
age: 12,
};
// 선언된 속성
console.log('name' in cat); // true
console.log(Object.hasOwn(cat, 'name')); // true
console.log(cat.hasOwnProperty('name')); // true
// 상속된 속성
console.log('toString' in cat); // true
console.log(Object.hasOwn(cat, 'toString')); // false
console.log(cat.hasOwnProperty('toString')); // false
2) 객체 선언 방식
- 객체를 생성할 때 prototype 방식이 아닌
Object.create()
을 사용할 수도 있다. - 대신 이렇게 생성된 객체에서는 prototype 메소드인
hasOwnProperty()
는 사용할 수 없다.
let cat = Object.create(null);
cat.name = 'lala';
console.log('name' in cat); // true
console.log(Object.hasOwn(cat, 'name')); // true
console.log(cat.hasOwnProperty('name')); // error
3) 오버라이드
- 만약 객체에서
Object.hasOwn
,hasOwnProperty
를 오버라이드하면 기존 기능은 작동되지 않는다.
const cat = {
hasOwnProperty: () => false,
name: '1',
};
Object.hasOwn = () => false;
console.log('name' in cat); // true
console.log(Object.hasOwn(cat, 'name')); // false
console.log(cat.hasOwnProperty('name')); // false
4) 클래스
- private(#)으로 선언된 속성에는 접근할 수 없다.
class Test {
#name = 1;
}
const test = new Test();
console.log('#name' in test); // false
console.log(Object.hasOwn(test, '#name')); // false
console.log(test.hasOwnProperty('#name')); // false
반응형
'개발 기술 > 사소하지만 놓치기 쉬운 개발 지식' 카테고리의 다른 글
[JS] Object.freeze, Object.seal의 차이 (0) | 2022.04.09 |
---|---|
Array.at(), 배열 인덱스 값에 접근하는 방법 (0) | 2022.04.06 |
[JS] JSON.stringify, 세 개의 인자 (0) | 2022.03.30 |
[JS] 크기 변화를 감지하는 두 가지 방법(resize, ResizeObserver) (0) | 2022.03.26 |
[JS] JS에서 요소의 스타일 접근하는 방법 (0) | 2022.03.23 |
댓글