티스토리 뷰

🐱‍👤목차

  • 함수의 활용(리팩토링이란?)
  • 객체(쓰고 읽기, 반복문, 프로퍼티와 메소드)
  • JS명명 규칙은 [유용한 사이트]쪽에 따로 빼놓았음
  • 파일로 쪼개서 정리하기(장점 상세 설명)

😛function(함수)의 활용 

리팩토링: 동작하는 내용은 같지만 코드를 효율적으로 하는 것 

->리팩토링에서 아주 중요한 역할을 하는 것이 함수입니다. 

 

리팩토링하기 위해서 가정을 해봅시다.

버튼이 1억개가 있다면 같은 코드를 여러곳에 복붙해놓는 것보단 함수를 통해 관리하는 것이 좋겠죠?

 

 function nightDayHandler() {
        const target = document.querySelector("body");
        if (this.value === "night") {
          target.style.backgroundColor = "black";
          target.style.color = "white";
          this.value = "day";

          let alist = document.querySelectorAll("a");
          let i = 0;
          while (i < alist.length) {
            alist[i].style.color = "powderblue";
            i = i + 1;
          }
        } else {
          target.style.backgroundColor = "white";
          target.style.color = "black";
          this.value = "night";

          let alist = document.querySelectorAll("a");
          let i = 0;
          while (i < alist.length) {
            alist[i].style.color = "blue";
            i = i + 1;
          }
        }
      }

nightDayHandler라는 함수를 따로 만들었습니다. 내부 코드는 우리가 이전에 만들어놓은 onlcik이라는 이벤트 내부에 작성해놓은 JS코드와 같습니다.

주의할 점이 있다면 기존의 this가 가리키는 값이 원래는 해당 이벤트가 실행되는 태그였는데, 독립적으로 함수를 만들어주면서 다른 것을 가리키게 됩니다. 즉, 함수 내에서의 this는 input태그가 아니라 전역객체를 가리키게 됩니다(웹브라우저에서는 윈도우를 말한다네요). 고로 제대로 코드가 실행되지 않습니다.

function nightDayHandler(self) { //param으로 this를 담은 변수명self인 매개변수
        const target = document.querySelector("body");
        if (self.value === "night") {
          target.style.backgroundColor = "black";
          target.style.color = "white";
          self.value = "day";

          let alist = document.querySelectorAll("a");
          let i = 0;
          while (i < alist.length) {
            alist[i].style.color = "powderblue";
            i = i + 1;
          }
        } else {
          target.style.backgroundColor = "white";
          target.style.color = "black";
          self.value = "night";

          let alist = document.querySelectorAll("a");
          let i = 0;
          while (i < alist.length) {
            alist[i].style.color = "blue";
            i = i + 1;
          }
        }
      }

 

<input
      type="button"
      value="night"
      onclick=" 
    nightDayHandler(this); //arg 로 this를 보내줍니다
    "
    />

->이를 해결하기 위해서 우리는 arg 와 param을 쓸 겁니다. arg로 this를 보내고 this와 혼동하지 않도록 param의 이름을 self라고 작성하여 만들어줍니다. 당연히 함수 내부의 this는 self로 이름을 변경해줘야 겠죠!

 

😛객체(Object)

-서로 연관된 함수와 서로 연관된 변수를 같은 이름으로 그룹핑해서 잘 정리정돈하기 위한 도구

 

Q. 객체를 왜 사용해야 하나요? 에 관련된 예시 코드

 function linkSetColor(color) {
        let alist = document.querySelectorAll("a");
        let i = 0;
        while (i < alist.length) {
          alist[i].style.color = color;
          i = i + 1;
        }
      }
      function bodySetColor(color) {
        document.querySelector("body").style.color = color;
      }
      function bodySetBackgroundColor(color) {
        document.querySelector("body").style.backgroundColor = color;
      }
      function nightDayHandler(self) {
        const target = document.querySelector("body");
        if (self.value === "night") {
          bodySetBackgroundColor("black");
          bodySetColor("white");
          self.value = "day";

          linkSetColor("powderblue");
        } else {
          bodySetBackgroundColor("white");
          bodySetColor("black");
          self.value = "night";

          LinkSetColor("blue");
        }
      }

위의 코드는 좋은 코드가 아닙니다.

이유 -> setColor라는 함수명이 겹쳐서 결국 부가설명을 붙여 함수의 이름을 길게 만들어줘야했죠 만약에 이러한 함수가 엄청 많다면 같은 이름의 함수가 겹치게 되면서 가장 최근의 함수만 기능하게 되고 전에 것은 무효화됩니다. 이런 상황이 오면 끔찍하겠죠

-> 많은 함수를 정리정돈하기 위한 도구가 바로 객체입니다. 객체를 하나의 폴더라고 생각하시면 이해하기 쉽습니다. 

  • 함수(functino) 코드가 많아지면 정리정돈하는 도구
  • 객체(Object)함수와 변수가 많아지면 연관된 것들을 서로 그룹핑하여 정리정돈하는 도구

객체 쓰기와 읽기

배열: 정보를 담는 그릇이면서 정보가 순서대로 저장된다는 특징을 가진 도구

Q. 그렇다면 순서없이 정보를 저장할 수 있는 것은 무엇일까? 바로 객체입니다.

객체는 꺼낼 필요가 있는 물건을 담는 상자이기 때문에 이름이 있는 정리정돈 상자라고 생각하면 된다.

 

생성하는 법 

  • 배열(Array)은 대괄호[]
  • 객체(Object)는 중괄호{} 

 

객체와 반복문(객체의 데이터를 순회하는 방법)

객체의 반복문 처리가 궁금하면 검색을 해보시면 됩니다. 

*여기서 반복이라고 해서 loop라고 검색하기 보다는 javascript object iterate(v.순회하다)라고 검색하는 것이 좋습니다.

스택오브플로우의 검색결과

객체에서 key를 우리가 가져오고 싶은 정보에 도달할 수 있는 열쇠 라고 생각하면 됩니다. 

반면, 배열은 순서대로 들어가 있기 때문에 key라는 개념은 없고 index 라고 표현합니다. 

->당연히 객체의 반복문 결과물은 순서없이 랜덤으로 나오게 되겠죠 

    <h1>Object</h1>
    <h2>Create</h2>
    <script>
      // 객체 생성하는 법
      const coworkers = {
        //key : value
        florist: "gamza",
        designer: "cong",
      };
      //만들어진 객체의 데이터를 가져오는 법
      // 설명: object. 할때 객체 뒤에 붙는 dot 은 object access operator 라고 부릅니다.
      document.write(`The florist is ${coworkers.florist}`);
      //객체에 새로운 데이터 추가하기

      coworkers.animal = "monkey";
      document.write(`The animal is ${coworkers.animal}`);
      //key 이름에는 띄어쓰기할 수 없습니다. 배열에서 어떤 정보를 가져올때 []를 사용하는 것처럼
      //["data scientist"]를 하면 띄어쓰기를 할 수 있습니다.
      // 대괄호를 썼을 때는 이를 불러올 때도 대괄호 형식으로 불러와야 합니다.
      coworkers["data scientist"] = "koko";
      document.write(`The data scientist is ${coworkers["data scientist"]}`);
    </script>
    <h2>객체 순회하기(object iterate)</h2>
    <script>
      //coworkers라는 변수가 가리키는 객체에 있는 key값들을 가져오는 반복문
      //키값을 하나하나 꺼내서 중괄호 안의 코드를 실행시키는 것

      for (let key in coworkers) {
      //객체의 key값을 화면에 출력합니다. 
        document.write(key + "<br>");
      //객체의 value값을 화면에 출력합니다. 
      //->배열에서 index로 해당값을 찾는 것처럼 []대괄호를 사용하여 key에 해당하는 value를 알 수 있습니다. 
        document.write(coworkers[key] + "<br>");
      //두 가지를 백틱을 활용해서 화면에 출력하기
        document.write(`key and value are ${key} : ${coworkers[key]} <br>`);
      }
    </script>

 객체 프로퍼티와 메소드

  • 객체에는 문자뿐만 아니라 배열,숫자,함수 등등 많은 것을 담을 수 있습니다.
  • 객체에 소속된 함수를 메소드라고 부릅니다.
  • 객체에 소속된 변수를 프로퍼티라고 부릅니다. e.g.) key값들
  • 객체 내부의 프로퍼티들을 구분할 때 콤마(,)를 사용합니다.

 

객체의 함수(메소드) 생성 방법

  • 함수를 만드는 형식에 있어서는 "객체명."이 앞에 붙는다는 것 빼고는 같습니다. 
  • const 의 자리에 let도 당연히 가능합니다.

객체 메소드 만들기 예제

<script>
      //coworkers라는 객체에 showAll이라는 함수를 만들었습니다.
      coworkers.showAll = function () {
        for (let key in coworkers) {
          document.write(`key and value are ${key} : ${coworkers[key]} <br>`);
        }
      };
      coworkers.showAll();

※이슈: 하지만 이 함수에는 약점이 있는데요. 바로 coworkers라는 객체명이 변경되면 제대로 작동하지 않는다는 점입니다. 우리는 이전에 배웠던 input태그에 onclick예제를 기억해보시면 input태그 자체를 가리키는 "this"라는 키워드를 기억해봅시다. 이 함수에서 this 키워드의 의미"이 함수가 소속된 객체 자체를 가리키는 약속된 기호"입니다. 

그렇다면 함수 내부(중괄호 내부 코드)에 작성되어있는 객체명을 this로 변경해주면 객체명(=객체를 담은 변수명)이 변경되어도 잘 작동되겠죠. 

*편의상 함수라고 작성했지만 위에서도 언급했듯이 객체 내부의 함수는 "메소드" 라고 부릅니다.

 

메소드 수정(obj명 -> this)

 coworkers.showAll = function () {
        for (let key in this) {
          document.write(`key and value are ${key} : ${this[key]} <br>`);
        }
      };
      coworkers.showAll();

▶객체를 활용한 코드 만들기

let Link = {
        setColor: function (color) {
          let alist = document.querySelectorAll("a");
          let i = 0;
          while (i < alist.length) {
            alist[i].style.color = color;
            i = i + 1;
          }
        },
      };
      // function linkSetColor(color) {
      //   let alist = document.querySelectorAll("a");
      //   let i = 0;
      //   while (i < alist.length) {
      //     alist[i].style.color = color;
      //     i = i + 1;
      //   }
      // }
      let Body = {
        SetColor: function (color) {
          document.querySelector("body").style.color = color;
        },
        SetBackgroundColor: function (color) {
          document.querySelector("body").style.backgroundColor = color;
        },
      };
      // function bodySetColor(color) {
      //   document.querySelector("body").style.color = color;
      // }
      // function bodySetBackgroundColor(color) {
      //   document.querySelector("body").style.backgroundColor = color;
      // }
      function nightDayHandler(self) {
        const target = document.querySelector("body");
        if (self.value === "night") {
          Body.SetBackgroundColor("black");
          Body.SetColor("white");
          self.value = "day";

          link.SetColor("powderblue");
        } else {
          Body.SetBackgroundColor("white");
          Body.SetColor("black");
          self.value = "night";

          Link.SetColor("blue");
        }
      }

Q. 궁금한 점이 있는데 JS 명명 규칙에 의하면 객체는 소문자 카멜 케이스인 것으로 아는데 왜 이고잉님은 body나 link를 대문자로 시작했는지 궁금함.. 추측해보면 Body나 Link가 HTML해당 태그를 바꿔주는 것이므로 일부러 저렇게 작성하신 거 같다..?

 

😛파일로 쪼개서 정리하기

예시로 만들었던 js코드는 전부 HTML의 script 내부에 직접 작성한 것들입니다. 하지만 이렇게 되면 유지보수가 어렵게 되겠죠.내가 만든 JS코드를 1억개의 웹페이지에 적용해야 한다고 했을 때의 가정입니다. 객체보다 큰 단위를 정리정돈 하기 위해서 이제 우리는 js코드를 파일로 쪼개서 정리할 것입니다. 사용법은 간단합니다. 기존의 코드가 있던 script의 내용물을 .js파일로 따로 분리시켜주면 됩니다. 그리고 적용해야할 웹페이지에 <script src="어쩌구.js"> </script>  이 한 줄짜리를 삽입해줍니다.

 

 

▶파일로 쪼개서 정리하는 것의 장점

 

이렇게 파일로 쪼개면 JS파일을 다운받아야 하기 때문에 1번 접속할 웹 서버를 웹 서버에 2번 접속하게 됩니다.

(*F12에서 Network를 가면 알 수 있습니다.) 웹 서버입장에서 접속은 적을수록 좋다고 합니다. 그럼에도 불구하고 이 방법이 효율적인 이유는 캐시때문입니다. 캐시(cache)는 저장한다는 뜻입니다. 한 번 웹페이지에 다운로드된 파일은 보통 웹브라우저가 컴퓨터에 저장해놓습니다. 그리고 다음에 접속할 때, 저장된 파일을 읽어서 네트워크를 통하지 않게 만듭니다. 결론적으론 서버입장에서 비용절감이 되고 사용자 입장에선 네트워크 트래픽 절감 + 빠른 웹페이지 화면표시가 가능해집니다. ->돈과 시간 측면에서 효율적인 것

 

 

댓글