몽키패치(Monkey patch)가 무엇인지 알아보고 예제와 단점을 알아보자
몽키패치란(Monkey patch)
몽키패치는 원래 소스코드를 변경하지 않고 실행 시 코드 기본 동작을 추가, 변경 또는 억제하는 기술이다. 쉽게 말해 어떤 기능을 위해 이미 있던 코드에 삽입하는 것이다.
자바스크립트의 endwWith 함수를 예를 들어보자. 이 함수는 어떤 문자열에서 특정 문자열로 끝나는지를 확인할 수 있으며, 그 결과를 true 혹은 false로 반환한다. 만약 이 함수가 없었다면 이 기능을 어떻게 구현했을까
첫 번째 방법은 유틸리티 객체를 만드는 것이다.
var Utility = {
endsWith: function(string, suffix) {
return string.indexOf(suffix, string.length - suffix.length) !== -1;
}
};
var isSuffix = Utility.endsWith('hello world', 'ld');
다른 방법은 String 내장 객체에 함수를 정의하는 것인데, 이게 바로 몽키패치이다.
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
var isSuffix = 'hello world'.endsWith('ld');
몽키패치의 다른 예로 console.log에 타임스탬프를 찍어보자
var log = console.log;
console.log = function() {
log.apply(console, [(new Date()).toString()].concat(arguments));
};
몽키패치를 사용하면 console.log를 재정의 또는 확장하여 타임스탬프를 찍는 console.log를 만들 수 있다. 이렇게 보면 몽키패치가 편하고 좋아 보이지만 꼭 그런 건 아니다.
몽키패치의 단점
원숭이 패치는 종종 위험한 기술로 간주된다. 왜냐하면 몽키패치는 기존 코드와의 충돌이 있을 수 있기 때문이다.
String.prototype.constains()가 String.prototype.includes()로 변경된 일이 있었는데, 그 이유는 MooTools 라이브러리를 사용하는 코드들이 String.prototype.containts 함수의 충돌로 인해 버그가 발생한 것이다. MooTool's String.prototype.contains conflicts with ES6 깃헙 이슈를 보면 더 자세히 알 수 있다.
이처럼 몽키패치가 내장 객체에 사용될 때 언어의 발전을 방해할 수 있다. 몽키패치는 언어, 라이브러리, 프레임워크 등 모든 코드로 확장될 수 있다. 몽키패치를 사용할 때 기능이 충돌하여 버그가 발생할 가능성을 염두해야 한다.
몽키패치를 사용하는 경우
몽키패치가 좋은 케이스 중 한 가지는 이미 ECMAScript 표준의 일부이고 모든 브라우저에서 지원되지 않는 메서드를 폴리필하는 경우이다. 이 방법은 이미 표준화되어 있으므로 서명과 정확한 동작을 알 수 있으므로 안전한 몽키패치이다.
그리고 이미 정의된 함수 또는 코드가 없는 경우에 몽키패치를 사용하는 것도 안전하고 좋은 방법이다.
예를 들어 String.prototype.includes() 함수를 지원하지 않는 브라우저에서는 아래처럼 몽키패치를 사용할 수 있다.
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
'개발' 카테고리의 다른 글
axios major version 업데이트 (0) | 2022.11.26 |
---|---|
JSONP 용도, 동작 정리 (0) | 2022.11.19 |
console.log 시간 출력 (0) | 2022.09.30 |
axios 캐시 적용 및 원리 (by axios-extensions) (0) | 2022.09.24 |
자바스크립트 reduce 사용 시 주의점 (0) | 2022.09.21 |