Web/JS

[JS] eslint를 사용할 때 hasOwnProperty 사용 시 오류

메바동 2023. 5. 9. 14:47
728x90

 

Do not access Object.prototype method 'hasOwnProperty' from target object.

대상 오브젝트에서 Object.prototype 메서드 'hasOwnProperty'에 액세스 하지 마세요.

 

 

eslint를 사용할 경우 no-prototype-builtins라는 규칙에 위배되어 오류가 나타나게 된다.

 

해당 항목을 읽어보니 ECMAScript 5.1에서 지정된 [[Prototype]]을 가진 객체를 생성할 수 있는 Object.create 함수가 추가되었는데, Object.create(null)을 사용하여 객체를 생성할 경우 Object.prototype을 상속받지 않아 오류를 일으킬 수 있기 때문에 Object.prototype 메서드를 직접 호출하지 못하도록 한다고 한다.

 

// Object.prototype을 상속받지 않음
const obj1 = Object.create(null);
obj1.foo = 'Hello, world!';

// Object.prototype을 상속받지 않기 때문에 에러 발생
obj1.hasOwnProperty('foo');

 

또한, 객체에서 Object.prototype의 기본 제공을 가리는 속성이 있을 수 있으므로 의도하지 않은 동작이나 서비스 거부 보안 취약점이 발생할 수 있어 위와 같은 방법으로 호출하는 것이 바람직하지 않은 것이다.

 

// 객체의 속성에 의해 Object.hasOwnProperty가 가려짐
const obj2 = {
  hasOwnProperty: () => console.log('Hello, world!'),
  foo: 'Hello, world!',
};

// 원하는 동작과 다른 동작이 수행 됨
obj2.hasOwnProperty('foo');

 

따라서 이런 문제를 방지 하기 위해 Object.prototype의 메서드를 이용할 때는 다음과 같은 방식으로 사용하는 것이 안전한 방식이라고 한다.

 

Object.prototype.{method}.call(obj, {...params});

 

위에서 문제가 발생한 코드들에서 다음과 같이 호출하면 원하는 대로 동작하는 것을 볼 수 있다.

 

// Object.prototype을 상속받지 않음
const obj1 = Object.create(null);
obj1.foo = 'Hello, world!';

// Object.prototype을 상속받지 않기 때문에 에러 발생
// obj1.hasOwnProperty('foo');

// true
console.log(Object.prototype.hasOwnProperty.call(obj1, 'foo'));

// 객체의 속성에 의해 Object.hasOwnProperty가 가려짐
const obj2 = {
  hasOwnProperty: () => console.log('Hello, world!'),
  foo: 'Hello, world!',
};

// 원하는 동작과 다른 동작이 수행 됨
// obj2.hasOwnProperty('foo');

// true
console.log(Object.prototype.hasOwnProperty.call(obj2, 'foo'));

 

 

 

react에서 hasOwnProperty를 사용하여 조건문을 주려고 했는데 해당 상태가 초기값이 null이라 ?.hasOwnProperty를 사용하여 null에 대한 오류를 방지하려고 했었는데 위 방법을 사용하면서 다음과 같은 방법으로 null 체크를 해주었다.

 

if (obj && Object.prototype.hasOwnProperty.call(obj, ...)) {
	// do something...
}
728x90