본문 바로가기
뒷북 정리 (국비 교육)/javascript

[javascript] step01. datatype : object (plane object, array)

by 규글 2021. 12. 8.

object (plane object, array)

a. plae object

    <script>
        // 회원 한 명의 정보라고 가정하자
        // 각각의 변수에 대입하면 3개의 변수가 필요하지만
        let num = 1;
        let name = "김구라"
        let isMan = true;

        // 다른 data type을 활용하면 1개의 변수명으로
        // 회원 한 명의 정보를 관리할 수 있다.
        let mem1 = {num:1, name:"김구라", isMan:true};
        let mem2 = {num:1, name:"김구라", isMan:true};
        let mem3 = {num:num, name:name, isMan:isMan};

        // a is object type
        let a = mem1;   // mem1에 있는 object type value를 a에 복사
        // b is number type
        let b = mem1.num;   // 
        // c is string type
        let c = mem1.name;  // 
        // d is boolean type
        let d = mem1.isMan; // 

        // object에 저장된 값을 수정하기
        mem2.num=999;
        mem2.name="이정호";

        // 빈 object를 만들고
        let mem4 ={};
        // 나중에 방을 추가할 수 있을까요?
        mem4.num = 2;
        mem4.name="해골";
        // 나중에 방을 삭제할 수 있을까요?
        delete mem4.name; // delete 예약어를 이용해서 삭제한다.
    </script>
  1. object type의 필요성 : 예시처럼 한 사람의 정보를 관리함에 있어서 3개의 변수명이 필요하고, 사람이 다수라면 머리가 아파진다. 하지만 object type으로 관리한다면 하위 항목 내용에 대한 하나의 변수명으로 관리할 수 있게 된다.
  2. 중괄호 {  }를 이용하여 만든다. 내용에는 key1 : value1, key2 : value2, ... 가 들어가는데, 여기에서 key를 repository(저장소) name, value를 repository라고 한다고 했다. 이렇게 구성된 object를 plain object라고 한다.
    (plain이라고 하면 다른 종류의 object도 있다는 것인가?)
  3. object의 내용 참조하기 : object에 .을 붙여서 내용을 참조할 수 있다. 이 point(. : 점)는 object와 관련이 있다.
  4. 예시의 a에 mem1을 대입했다. 그러면 a==mem1 했을 때 true가 나온다. 하지만 같은 내용을 작성해서 mem1a에 대입하더라도 mem1==mem1a 는 false가 나온다. 이는 object 통째로 변수에 들어가는 것이 아니기 때문이다.
    예를 들어 사물함에 빗댄다면, {  }는 사물함에 들어가고 변수에는 그 사물함의 번호가 들어간다. 즉, a=mem1을 하더라도 a에 mem1 object 자체가 들어간 것이 아니라 같은 사물함 번호를 공유하는 셈이다.
    때문에 object의 값에는 사물함 번호가 들어가지만, 그 값을 볼 수는 없다. 상상의 나래를 펼쳐보자.
  5. 예시에서 a에 점을 찍나, mem1에 점을 찍나 같은 결과가 나오는 이유이다. 같은 사물함 번호를 공유하기 때문.
  6. object의 내용을 수정하는 것도 가능하다.
  7. value에 미리 만들어진 값을 참조해서 쓰기도 한다.
  8. object에 빈 방(key)을 추가하는 것도 가능하다. 만약에 해당 이름으로 된 key가 있다면 덮어서 써지고, 없다면 새로 만들어지면서 들어간다. 추가가 가능한 만큼 삭제도 가능하다. 삭제는 delete 예약어를 이용한다.

 

b. array

    <script>
        // 상품 하나의 정보라고 가정 (나열 순서가 중요하지는 않은 정보이다.)
        // object는 순서가 없는 데이터이다.
        let obj = {num:1001, name:"삼겹살", price:"10000원", expireDate:"2020.06.10"};
        
        // 때로는 순서가 중요한 데이터도 있지 않을까?
        // 많음!!
        // 예를 들어 내가 좋아하는 음식 목록
        let one = "초밥";
        let two = "소고기";
        let three = "마라탕";
        let four = "떡볶이";
        let five = "파스타";

        // let obj2 = {one two three ...};
        // 순서가 중요한 데이터는 array (배열에 저장한다)
        let myFavorite = ["초밥", "소고기", "마라탕", "떡볶이", "파스타"];
        // 배열의 특정 방을 참조해서 대입하기
        let a = myFavorite[0];
        let b = myFavorite[1];
        let c = myFavorite[2];

        // 배열의 특정 방 참조해서 수정하기
        myFavorite[0] = "라면";
        myFavorite[1] = "삼겹살";

        // 배열에 아이템 추가하기
        myFavorite.push("피자");
        myFavorite.push("맥주");

        // 배열의 방의 개수 참조
        let size = myFavorite.length;

        // .splice(삭제할 index, 삭제할 개수)
        myFavorite.splice(2,1); // 2번 index로부터 1개 삭제
    </script>
  1. object는 순서가 중요하지는 않다. 하지만 순서가 중요하다면 array(배열)를 이용한다.
  2. array[#] 의 형태로 배열을 참조할 수 있다. #은 0부터 시작한다.
  3. 하지만 plane object {  } 와 array [  ] 모두 object type이다.

  4. length : 배열의 길이를 알 수 있다.
    push : 배열에 item을 추가할 수 있다.
    splice(a,b) : 배열의 a index로부터 b개의 item을 잘라낼 수 있다. splice의 경우 잘라서 보기만 하는 것이 아니라 아예 잘라서 가져오는 것이다. 남은 item들은 순서를 유지한 채 빈 공간을 당겨서 채우게 된다.

    이들을 . 으로 참조해서 사용하게 되는데, 즉 array는 외형상은 array이지만 {length:xxx, push:function(  ){  }, ...} 의 object이기도 한 것이다. 이때의 length와 push는 내장된 기본 기능이라고 할 수 있다. 그리고 이 item들을 동시에 참조하는 것은 불가능하다.

 

    <script>
        // 배열에는 주로 한 가지 type의 data만 담는 것이 일반적이다.
        let nums = [10, 20, 30, 40, 50];
        let names = ["김구라", "해골", "원숭이", "주뎅이", "덩어리"];
        let data = [true, true, false, false, true];
        /*
        let mem1 = [1, "김구라", true, "노량진", "삼성", 90, function(){
            alert("array 안에 있는 function이 호출되었습니다.")
        }];
        let mem2 ={
            num:1,
            name:"김구라",
            isMan:true,
            address:"노량진",
            company:"삼성",
            iq:90
        };
        */

        let members = [
            {num:1, name:"김구라", address:"노량진"},
            {num:2, name:"해골", address:"행신동"},
            {num:3, name:"원숭이", address:"상도동"}
        ];

        let a = () => {}; /// 이건 오류가 아닌데 나중에 배울것.
    </script>
  1. 그렇다면 배열에는 어떤 data를 담는 것이 좋을까? number, string, boolean...
    이들을 섞을 수도 있지만 일반적으로는 그렇게 쓰이지 않는다. 예를 들어 [김구라, true, 노량진, 삼성, 90] 으로 구성된 배열은 각 내용이 어떤 것을 의미하는지 알 수 없다. 때문에 배열에는 주로 한 가지 type의 data를 담는다.
  2. 함수도 값이기 때문에 array 안에 들어갈 수 있다.(주석) 함수가 특정 값을 return한다면 그 자리는 return되는 값이 들어가겠지만, 딱히 return하는 값이 없다면 undefined가 된다.
  3. array안에 object들이 들어가는 것도 가능하다. 이 경우에는 각 object에 대한 사물함 번호들이 배열의 item이 되는 것이라고 상상하면 좋다.
  4. a = ( ) => { }; : 오류가 아니다. 추후에 배울 예정이라고 했다.

 

 

21.04.16. object 내용 추가

  1. new의 의미는 heap 영역에 object를 생성하는 것이다. 그리고 변수에 heap 영역에 생성된 object의 reference value (참조값)를 담는 것이다. (ex - new Image(  ), new Audio(  ), new Data(  )...)
    이전에 만들었던 plane object와 array도 정석은 new를 통해서 만드는 것이었다.
    let obj1={};
    let obj2=new Object();
    
    let arr1=[];
    let arr2=new Array();​
    이전에는 약식으로 단순히 중괄호만으로 object를, 대괄호만으로 array를 만들었으나 정석은 그 아래에 new 로 만드는 것이라고 했다. 중괄호와 대괄호는 편의를 위한 약식이라고 한다.
  2. object는 저장소(ex - .length)와 기능(ex - forEach(  ))로 이루어져 있다.
    이 두 가지 모두 만들 수 있다. (ex - obj.name="xxx" / obj.drive=function(  ){  })
  3. 이렇게 new 로 만들어지는 것은 그냥 함수는 아니고 '생성자 함수'라고 한다. (나중에 배울 class의 개념이라고 했다.)
    'new' 라는 예약어로 미리 설계된 무언가를 사용하는 정도로 인지하고 있으면 된다고 했다.

    function Person(name, gender) {
      this.name = name;
      this.gender = gender;
    }
    Person.prototype.sayHello = function() {
      alert(this.name + ' said "hello"');
    };​

    (추가 search)
    생성자 함수의 이름은 대문자로 시작해야 한다. 소문자로 작성하게 된다면 새로이 객체를 생성하는 것이 아니라 그냥 일반적인 함수를 만드는 것이라고 한다.[각주:1]
    prototype이라는 것을 검색하다가 함께 발견하게 되었는데, 글자 그대로 객체의 prototype에 대한 정보를 담는다고 생각하면 될 것 같다. 객체를 만들게되면 해당 객체마다 메모리를 할당받을텐데, 동일한 동작에 대한 객체를 계속해서 만들게 된다고 생각하면 무의미한 메모리 할당이 될 것이다. 때문에 그런 동일한 내용을 prototype에 만든다면 해당 문제를 해결할 수 있다고 되어 있었다.[각주:2]

댓글