프로젝트 내에서 공통으로 사용하기 위해서 prototype에 확장함수를 등록하여 사용하던 중 문제가 발생했다.
확장함수를 포함하여 개발된 라이브러리를 html에서 import하고 페이지를 로드하니 정상적으로 동작하던 기능들이 정상동작하지 않는 문제가 발생했다.
일반적으로 Array.prototype.forEach
또는 Array.prototype.map
을 사용하여 배열의 요소들을 다뤘는데, 공동으로 작업하다 보니 for (let i in array)
와 같은 방법으로 처리한 코드가 존재했기 때문이다.
문제가 발생한 사항은 다음과 같다.
if(!Array.prototype.hasOwnProperty('fname')) {
Array.prototype.fname = function(){}
}
for (let i in [1, 2, 3]) {
console.log(i)
}
위와 같은 코드를 입력하면 다음과 같은 결과를 예상할 것이다.
1
2
3
하지만 실제 결과는 다음과 같았다.
1
2
3
fname
왜 이런 일이 발생했는가 하니, for...in
문법은 object의 모든 property를 대상으로 순회를 하는데, Array.prototype.A = ...
식으로 공통 함수를 등록하게 될 경우에도 property 취급을 하기 때문이다.
위의 개발문서에서 발견한 추가적인 문제 중 하나는 for...in 을 사용하게 될 경우 Array 내 index 순서 보장 되지 않아 개발자가 의도한 결과와 다른 결과가 도출될 수 있다고 한다.
이를 해결하기 위해 조치한 코드는 다음과 같다.
if(!Array.prototype.hasOwnProperty('fname')) {
Object.defineProperty(Array.prototype, "fname", {
enumerable: false,
value: function() {}
})
}
위와 같이 prototype에 property를 정의하면 더이상 for...in
에서 임의로 정의한 확장함수가 노출되는 경우는 발생하지 않는다.
다만, Array의 순회를 위해선 for...in
대신 Array.prototype.forEach
또는 Array.prototype.map
를 사용할 수 있도록 주의를 주어야 할 것 같다.