Web/Frontend

생성자 패턴으로 TabUI 만들기

WakaraNai 2021. 7. 7. 19:40
728x90
반응형

자바스크립트의 객체 리터럴

var healthObj = {
  name : "달리기",
  lastTime : "PM10:12",
  showHealth : function() {
    console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
  }
}

healthObj.showHealth();

 

이와 같은 객체가 여러 개 필요하다면?

healthObj2, healthObj3 .. 중복하여 여러개를 만드는 방법 외에는?

 

객체를 동적으로 생성하는 방법

함수를 이용

h는 객체.

h안에 Health 함수를 한 번 더 불러서 h2 객체를 만듦

function Health(name, lastTime) {
  this.name = name;
  this.lastTime = lastTime;
    this.showHealth = function(){...}
}
const h = new Health("달리기", "10:12");
h2 = new Health("걷기", "20:11");

 

Health 함수는 new 키워드로 불리면서, 객체를 생성하는 함수 역할을 한다

그러므로 이 함수는 생성자(constructor)라고 함

 

 

그러나 h와 h2에는 showHealth 메소드가 여전히 중복되어 존재

이처럼 동일한 메소드가 여기저기 메모리 공간을 차지하면 자원 낭비

 

 

prototype으로 메소드를 같이 사용해보자

자바스크립트는 prototype이란 공간을 통해

객체 간 재사용을 관찰할 수 있도록 해둠

 

prototype 타입은 상속과 비슷한 개념

아래 그림에서 각 객체(h, h2, h3)가 prototype이라는 같은 참조객체를 바라보고 있음

따라서 prototype에 어떠한 속성을 변경하면 모든 인스턴스에게 공유된다

 

prototype에 어떠한 속성을 추가하면서 실제 코드로 확인해보자

아래 코드에는 Health 함수 아래 prototype 객체가 존재하고, 이것에 showHealth 메소드를 속성을 추가

이런 식으로 prototype 객체 안에 여러 가지 속성을 추가할 수 있음

function Health(name, lastTime) {
  this.name = name;
  this.lastTime = lastTime;

}

Health.prototype.showHealth = function() {
    console.log(this.name + "," + this.lastTime);
}

const h = new Health("달리기", "10:12");
console.log(h);  //크롬개발자도구를 열고 이 부분이 어떻게 출력되는지 확인해보세요
h.showHealth();

 

그럼 아래처럼 여러 객체를 만들어도 

prototype 안의 showHealth는 같은 참조점을 바라보고 있는 것을 알 수 있음

const h = new Health("달리기", "10:12");
const h2 = new Health("걷기", "14:20");
console.log(h.showHealth === h2.showHealth); //true

 

 

 

 

prototype 기반 클래스 코드

prototype 기반 코드는 하나의 클래스(모듈)을 만드는 것으로, 기존 코드의 큰 수정 없이 변경 가능

비슷한 기능을 묶어 하나의 객체, 즉 클래스 형태로 만들 수 있다

 

서버

파이썬으로 로컬 서버 돌리는 법

https://developer.mozilla.org/ko/docs/Learn/Common_questions/set_up_a_local_testing_server

 

cmd에서

해당 파일들이 존재하는 폴더로 이동

파이썬 버전에 따라 아래 명령어 입력

# 위에서 반환된 파이썬 버전이 3.X인 경우
python -m http.server
# 위에서 반환된 파이썬 버전이 2.X인 경우
python -m SimpleHTTPServer

 

주소창에 localhost:8000을 치면 html 파일이 로드되어 나옴

 

prototype 적용 전

<html>
<header>
    <link rel="stylesheet" href="tabui.css">
    <style>
    h2 {
    text-align: center
}

h2,
h4 {
    margin: 0px;
}

.tab {
    width: 600px;
    margin: 0px auto;
}

.tabmenu {
    background-color: bisque;
}

.tabmenu>div {
    display: inline-block;
    width: 146px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    cursor: pointer;
}

.content {
    padding: 5%;
    background-color: antiquewhite;
}
</style>
</header>

<body>
    <h2> TAB UI TEST</h2>

    <div class="tab">
        <div class="tabmenu">
            <div>crong</div>
            <div>jk</div>
            <div>pobi</div>
            <div>honux</div>
        </div>
        <section class="content">
            <h4>hello jk</h4>
            <p>golf, facebook</p>
        </section>
    </div>
    <script>

        function makeTemplate(data, clickedName) {
            var html = document.getElementById("tabcontent").innerHTML;
            var resultHTML = "";

            for (var i = 0; i < data.length; i++) {
                if (data[i].name === clickedName) {
                    resultHTML = html.replace("{name}", data[i].name)
                        .replace("{favorites}", data[i].favorites.join(" "));
                    break;
                }
            }
            document.querySelector(".content").innerHTML = resultHTML;
        }

        function sendAjax(url, clickedName) {
            var oReq = new XMLHttpRequest();
            oReq.addEventListener("load", function () {
                var data = JSON.parse(oReq.responseText);
                makeTemplate(data, clickedName);
            });
            oReq.open("GET", url);
            oReq.send();
        }

        var tabmenu = document.querySelector(".tabmenu");
        tabmenu.addEventListener("click", function (evt) {
            sendAjax("./json.txt", evt.target.innerText);
        });
    </script>

    <script id="tabcontent" type="my-template">
            <h4>hello {name}</h4>
            <p>{favorites}</p>
       </script>
</body>

</html>

 

 

적용 후 <script>

  <script>

    function Tab(tabElement) {
      this.tabmenu = tabElement;
      this.registerEvents();
    }

    // 객체 리터럴 정의할 때 arrow 함수는 지양하자
    Tab.prototype = {

      //전역 공간에 있는 내용도 옮길 수 있다.
      registerEvents: function () {
        this.tabmenu.addEventListener("click", function (evt) {
          this.sendAjax("./json.txt", evt.target.innerText);
        }.bind(this));
        //bind를 안하면 this는 tabmenu를 가리키게 됨
      },
      sendAjax: function (url, clickedName) {
        var oReq = new XMLHttpRequest();
        oReq.addEventListener("load", function () {
          var data = JSON.parse(oReq.responseText);
          this.makeTemplate(data, clickedName);
        }.bind(this));
        oReq.open("GET", url);
        oReq.send();
      },
      makeTemplate: function (data, clickedName) {
        var html = document.getElementById("tabcontent").innerHTML;
        var resultHTML = "";

        for (var i = 0; i < data.length; i++) {
          if (data[i].name === clickedName) {
            resultHTML = html.replace("{name}", data[i].name)
              .replace("{favorites}", data[i].favorites.join(" "));
            break;
          }
        }
        document.querySelector(".content").innerHTML = resultHTML
      }
    }

    var tabmenu = document.querySelector(".tabmenu");
    var o = new Tab(tabmenu);
    // 꼭 밖에서 만든 객체를 호출해주어야 실행됨

  </script>

 

 

 

결론

탭 말고 슬라이드라거나

자동완성 클래스, 어떤 메뉴, 다이얼로그 띄우기, 모바일 다이얼로그 띄우기 등의 네비게이션을

클래스로 나눠서 기능 별로 만들 수 있다

728x90
반응형

'Web > Frontend' 카테고리의 다른 글

form 태그로 데이터 보내기  (0) 2021.07.08
정규표현식 (regular expression)  (0) 2021.07.07
Clean Code  (0) 2021.07.06
handlebar를 활용한 템플릿 작업  (0) 2021.07.06
jQuery 프레임워크에 대해  (0) 2021.07.01