설명
- javascript legacy 소스코드 중
class(이하 OldClass)로 처리하고 있는 부분을 발견. - OldClass의 특정 method를
다른 js파일(이하 NewFile)에서 호출해야하는 상황 발생. - 문제는 OldClass에는 contructor 문이 작성되어 있어
NewFile 내에서 OldClass instance를 생성하기 어려운 상황. - OldClass의 해당 method를 뽑아내어
공용 js 파일로 분리시키는 것이 가장 좋으나
의존성 파악이 쉽지 않고 긴급하게 처리해야 하는 경우
OldClass instance를 window 객체에 할당하여
전역으로 접근할 수 있도록 조치하여 해결할 수 있다.
방법
- OldClass instance를 window 객체에 할당한다.
1 2 3 4 5 6
// old_class.js ... if (window) { window.addEventListener('DOMContentLoaded', function () { window['OldClass'] = new OldClass(); });
- window[‘OldClass’]로 할당하면 OldClass를 로드하고 있는 html이나
같은 html 내의 다른 js 파일에서 바로 OldClass instance로 접근할 수 있다.- OldClass를 로드하고 있는 html 예시
1
<button onclick="OldClass.SomeClickHandler()"></button>
- 같은 html 내의 다른 js 예시
1 2 3 4 5 6 7
class NewFile { constructor() { if (window && window['OldClass'] && window['OldClass'].SomeMethod) { window['OldClass'].SomeMethod(); } } }
- OldClass를 로드하고 있는 html 예시
예시
- 설명
- 글씨색: green, 배경색: pink인 버튼이 있다.
- OldClass에서는 글씨색을 변경하는 method가 있다.
- NewFile에서는 배경색을 변경하는 method가 있다.
- NewFile에서 버튼의 클릭 이벤트 함수를 지정한다.
- 버튼 클릭 시, 버튼을 글씨색:red, 배경색: yellow로 변경할떄
OldClass의 method를 호출하여 글씨색:red를 처리하고자 한다.
- 파일
- main.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="main.css" /> <title>hello world</title> </head> <body> <button id="my-btn" class="color-green bg-color-pink"> <strong>버튼</strong> </button> <script src="old_class.js"></script> <script src="new_file.js"></script> </body> </html>
- main.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
.color-green { color: green; } .color-red { color: red; } .bg-color-pink { background-color: pink; } .bg-color-yellow { background-color: yellow; }
- old_class.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
class OldClass { constructor() { console.log('Created OldClass instance'); } /** * 버튼 글씨색을 빨강으로 변경 */ changeBtnColorRed() { const btnElem = document.querySelector('#my-btn'); const colorClassName = 'color-red'; this.#changeColor(btnElem, colorClassName); } /** * className이 버튼 글씨색 class 인지 확인 * @param {string} className * @returns */ #checkColorClass(className) { return className.substring(0, 6) === 'color-'; } /** * elem의 글씨색을 className으로 변경 * @param {Element} elem * @param {string} className * @returns {boolean} 변경여부 */ #changeColor(elem, className) { if (elem && className) { const isColorClassName = this.#checkColorClass(className); if (!isColorClassName) { return false; } const oldClassNames = elem.classList; for (const oldClassName of oldClassNames) { if (this.checkColorClass(oldClassName)) { elem.classList.remove(oldClassName); } } elem.classList.add(className); return true; } return false; } } if (window) { window.addEventListener('DOMContentLoaded', function () { window['OldClass'] = new OldClass(); }); }
- new_file.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
class NewFile { constructor() { this.handleBtnClick(); } /** * 버튼이 눌렸을 때 동작을 지정 */ handleBtnClick() { const btnElem = document.querySelector('#my-btn'); btnElem.addEventListener('click', () => { this.changeBtnColorRedAndBgColorYellow(); }); } /** * 버튼의 글씨색을 빨강으로 * 배경색을 노랑으로 변경 */ changeBtnColorRedAndBgColorYellow() { const btnElem = document.querySelector('#my-btn'); const bgColorClassName = 'bg-color-yellow'; this.#changeBgColor(btnElem, bgColorClassName); if (window && window['First'] && window['First'].changeColor) { window['First'].changeBtnColorRed(); } } /** * className이 배경색을 변경하는 class인지 확인 * @param {*} className * @returns */ #checkBgColorClass(className) { return className.substring(0, 9) === 'bg-color-'; } /** * elem의 배경색을 className으로 변경 * @param {Element} elem * @param {string} className * @returns {boolean} 변경여부 */ #changeBgColor(elem, className) { if (elem && className) { const isBgColorClassName = this.#checkBgColorClass(className); if (!isBgColorClassName) { return false; } const oldClassNames = elem.classList; for (const oldClassName of oldClassNames) { if (this.#checkBgColorClass(oldClassName)) { elem.classList.remove(oldClassName); } } elem.classList.add(className); return true; } return false; } } if (window) { window.addEventListener('DOMContentLoaded', function () { window['NewFile'] = new NewFile(); }); }
- main.html
- 최초화면
- 클릭 후 결과