본문 바로가기

코딩공부/WEB2 - JavaScript

[9] 객체

- 객체의 특성, 존재 이유, 기능

객체 (Object)

"  이름이 있는 정리정돈의 수단 "

함수와 연관된 변수들이 많아질 때, 서로 연관된 함수와 서로 연관된 변수를 같은 이름으로 그룹핑하여 잘 정리 정돈하기 위한 도구

 

- 객체의 특징 :  객체에 소속된 함수를 만들 수 있다.

- 메소드 : 객체에 소속된 함수

- 프로퍼티 : 객체에 소속된 변수

 

다음 코드를 보면 중복된 코드가 존재한다.

 

일단 함수로 독립시켜 보자

링크 태그의 컬러를 설정하는 담당 함수, 설정할 색상을 함수 호출 시 아규먼트로 넘겨주고, 함수는 파라미터(매개변수)로 받아서 색상 처리

  <script>
    function setColor(color){
      var alist = document.querySelectorAll('a');
      var i=0;
      while( i < alist.length ){
          alist[i].style.color = color;
          i++;
      }
    }
    function nightDayHandler(self){
      var target = document.querySelector('body');

      if(self.value === 'night'){
        target.style.backgroundColor = 'gray';
        target.style.color = 'white';	//한 줄 중복이지만, 의미를 명확히하기 위해 함수화 추천
        self.value='day';

        setColor('orange');
      }else{
        target.style.backgroundColor = 'white';
        target.style.color = 'black';	//한 줄 중복이지만, 의미를 명확히하기 위해 함수화 추천
        self.value='night';

        setColor('black');
      }
    }
  </script>

 

※ 함수화 장점.

한 줄이라고 하더라도 그 의미가 좀 불명확하거나 시간이 흐른 뒤, 원래 무슨 뜻이었는지 파악하기 힘들다면 함수를 통해 그 로직에 이름을 부여하는 것은 좋은 방법이다.

 

하지만, 함수명이 동일하면 후에 나오는 함수로 덮어쓰워진다.

코드가 방대해서 내가 쓰려는 함수명이 이미 쓰인 것인지 파악하기 어려우면..?

 

단순히 setColor() 라고 하지 않고 누구에 대한 색상을 설정하는 건지 명확히 나타내 주는 것이 좋다.

LinksSetColor() , BodySetColor(), BodySetBackgroundColor()

    <script>
    function LinksSetColor(color){		// link 태그 color 설정 함수
      var alist = document.querySelectorAll('a');
      var i=0;
      while( i < alist.length ){
          alist[i].style.color = color;
          i++;
      }
    }
    function BodySetColor(color){		// body 태그 글꼴 color 설정 함수
      document.querySelector('body').style.color = color;
    }
    function BodySetBackgroundColor(color){	// body 태그 배경 color 설정 함수
      document.querySelector('body').style.backgroundColor = color;
    }
    function nightDayHandler(self){
      var target = document.querySelector('body');

      if(self.value === 'night'){
        BodySetBackgroundColor('gray');
        BodySetColor('white');
        self.value='day';

        LinksSetColor('orange');
      }else{
        BodySetBackgroundColor('white');
        BodySetColor('black');
        self.value='night';

        LinksSetColor('black');
      }
    }
  </script>

 

이런 식으로 이름을 다르게 함수들을 만들어서 사용해도 되지만,,, '객체'라는 것을 이용할 수 있다.

서로 연관된 함수와, 서로 연관된 변수들을 그룹핑하여 정리 정돈하기 위한 수납상자로서 '객체'라고 하는 것이 존재한다.

 

▶ 객체를 사용하는 쪽의 코드의 변화

LinksSetColor() , BodySetColor(), BodySetBackgroundColor() 를 객체로

Body 라는 객체를 만든다. 객체 뒤에 점(.)을 찍고 setColor() 와 setBackSetgroundColor() 를 써서 호출

Links 라는 객체를 만든다. 객체 뒤에 점(.)을 찍고 setColor()를 호출

-> Body.setColor(), Body.setBackgroundColor(), Links.setColor() 

 

※ 이름 자체로 Body 와 Links 를 붙이는 것보다 객체를 이용하면 ?

예를 들어 저장장치에 디렉토리가 존재하지 않는다면, 한 저장소에 들어있는 모든 파일들의 이름이 중복되지 않도록 파일명을 계속해서 길게 쓸 것이다. 하지만, 디렉토리(폴더)라는 도구가 있기 때문에 정리정돈이 가능하다. (동일한 파일명이어도 서로 다른 디렉토리에 위치하면 상관없음) 객체를 '폴더'라고 생각하면 된다.

 

document.querySelector('body').style.color = color;

document 는 객체이고, querySelector()는 documnet객체에 속해있는 함수라는 것을 알 수 있다.

객체에 속해있는 함수는 함수라고 하지 않고 '메소드(Method)' 라고 한다.

 

 


1. 객체의 쓰기와 읽기

"배열" : 정보의 양이 많아졌을 때 서로 연관된 정보를 정리 정돈하기 위해 사용

배열의 특징 - 순서에 따라서 정보를 정리 정돈한다.

 

순서 없이 정보를 저장할 수 있는 것이 "객체" - 이름이 있는 정리정돈 상자

객체 생성 with. object literal 

객체는 각 프로퍼티를 콤마(,)로 구분한다.

var 객체명 = {
  "이름표" : "값",
  "key" : "value",
  ....
}

 

    <script>
      var coworkers = {     //객체 정의
        "programmer":"egoing",
        "designer":"leezche"
      };
      document.write("programer : " + coworkers.programmer+"<br>"); //객체 호출
      document.write("designer : " + coworkers.designer+"<br>");
      coworkers.bookkeeper = "duru";    //객체 데이터 추가(1)
      document.write("bookkeeper : " + coworkers.bookkeeper+"<br>");
      coworkers["data scientist"] = "taeho";  //객체 데이터 추가(2) - key에 공백이 들어갈 경우
      document.write("data scientist : " + coworkers["data scientist"]+"<br>");
    </script>

 

※ 오류 날 경우 Chrome 으로 확인

SyntaxError 확인 - 우측 ex10.html:19 라인에서 에러발생 클릭

 

잘못된 문법으로 작성하여 error - 점(.)이 들어가면 안 됨

 

2. 객체와 반복문

목표 : 반복문을 이용해 객체 안의 모든 데이터를 가져오기

 

javascript object iterate

 

for ~ in 문을 사용하라고 권고하고 있다.

'coworkers' 라는 변수가 가리키는 객체(object)에 있는 키 값들을 {} 를 한번씩 수행할 때마다 하나 씩 가져와서 'key'라는 변수에 셋팅한 뒤,  {...code...} 중괄호{} 에 들어있는 코드들을 실행시켜주는 반복문

<script>
for(var key in coworkers){
        document.write(key+" : "+ coworkers[key]+"<br>");
      }
</script>

 

3. 프로퍼티와 메소드

객체의 value 값에는 문자뿐 아니라, 배열, 숫자 데이터 등을 담을 수 있다.

물론, 객체에는 함수도 담을 수 있다.

 

- 객체의 특징 :  객체에 소속된 함수를 만들 수 있다.

- 메소드 : 객체에 소속된 함수

- 프로퍼티 : 객체에 소속된 변수

 

기존에 만들어 놓은 coworkers 라는 객체에 'showAll' 이라는 '메소드'를 추가한다. 

    <script>
      // 객체에 '함수'라는 데이터 저장 
      // 메소드 정의 (1) - 객체 정의 코드 내에서
      showAll : function(){
      	//...code...
      }
      
      // 메소드 정의 (2) - 이미 만들어진 coworkers 에 '함수'데이터를 추가
      coworkers.showAll = function (){ 
        //...code...
      }
		
      // 함수를 정의하는 아래의 표현과 같은 의미라고 보면 된다.
      function showAll(){
        //...code...
      }
      
      var showAll = function(){
        //...code...
      }
    </script>

 

coworkers 라는 객체의 이름이 함수를 정의하는 코드 function(){} 내에 하드코딩되어있다.

객체의 이름이 바뀐다면...?

showAll 이라고 하는 함수 안에서 함수가 소속되어있는 객체를 가리키는 약속된 기호 "this"를 사용하면 된다.

coworkers라는 객체 변수명이 수정되어도 this 는 자기 자신을 가리키기 때문에 영향을 받지 않는 좋은 코드이다.

    <script>
      coworkers.showAll = function (){
        for(var key in this){
          document.write(key+" : "+ this[key]+"<br>");
        }
      }
      coworkers.showAll();
    </script>

객체 안의 모든 데이터를 출력하고 있으므로 마지막에 showAll이라는 메소드의 구현 내용도 출력된다. 원한다면 조건문을 이용해서 예외 처리하면 됨.

 


객체의 활용

 

목표 : 함수의 이름으로 중복되지 않도록 했던 코드를 객체를 활용하여 리팩토링

 

<!-- 수정 전 코드 -->
  <script>
    function LinksSetColor(color){
      var alist = document.querySelectorAll('a');
      var i=0;
      while( i < alist.length ){
          alist[i].style.color = color;
          i++;
      }
    }
    function BodySetColor(color){
      document.querySelector('body').style.color = color;
    }
    function BodySetBackgroundColor(color){
      document.querySelector('body').style.backgroundColor = color;
    }
    function nightDayHandler(self){ 
      var target = document.querySelector('body');

      if(self.value === 'night'){
        BodySetBackgroundColor('gray');
        BodySetColor('white');
        self.value='day';

        LinksSetColor('orange');
      }else{
        BodySetBackgroundColor('white');
        BodySetColor('black');
        self.value='night';

        LinksSetColor('black');
      }
    }
  </script>

 

<!-- 수정 후 코드 -->
  <script>
    var Body = {    //객체생성
      setColor : function(color){   //메소드 정의(1) - 객체 정의 구현 부분에서 메소드 정의
        document.querySelector('body').style.color = color;
      }
      // },
      // setBackgroundColor : function(color){
      //   document.querySelector('body').style.backgroundColor = color;
      // }
    }

    Body.setBackgroundColor = function(color){  //메소드 정의(2) - 생성한 객체에 메소드 추가
      document.querySelector('body').style.backgroundColor = color;
    }

    var Links = {
      setColor : function(color){
        var alist = document.querySelectorAll('a');
        var i=0;
        while( i < alist.length ){
            alist[i].style.color = color;
            i++;
        }
      }
    }
    function nightDayHandler(self){
      var target = document.querySelector('body');

      if(self.value === 'night'){
        Body.setBackgroundColor('gray');
        Body.setColor('white');             //Body 객체의 setColor 메소드 호출  
        self.value='day';

        Links.setColor('orange');           //Links 객체의 setColor 메소드 호출
      }else{
        Body.setBackgroundColor('white');
        Body.setColor('black');
        self.value='night';

        Links.setColor('black');
      }
    }
  </script>

 

 

객체가 무한히 많아지면....? 객체보다 큰 정리도구...? 폴더!