[Day 19] 객체 + 배열

객체 (Object)

  • 한꺼번에 여러 값을 담을 수 있는 통(container)과 같은 자료구조.

  • 객체 안에는 이름-값 쌍(name-value pair)이 저장되는데, 이를 객체의 속성(property)이라고 한다.

  • 속성 접근자(property accessor)

    • 점 표기법 : person.name = '이름';
    • 대괄호 표기법 : person['한국 나이'] = 20;
      • 자바스크립트에서 식별자로 허용되지 않는 문자가 들어간 속성 이름을 사용해야 하는 경우에는 반드시 대괄호 표기법을 사용해야 한다.
      • 접근하고자 하는 속성 이름을 현재 시점에서 모르는 경우에도 대괄호 표기법을 사용한다. (ex. 사용자 입력을 받아 속성을 생성하거나 할 때)
  • 객체 다루기

    // 속성 삭제하기
    delete person.address;
      
    // 속성이 객체에 존재하는지 확인하기
    'name' in person;	// true
    
  • 메소드 (Method)

    • 어떤 객체의 속성으로 접근해서 사용하는 함수

      const person = {
        greet: function() {
          return 'hello';
        }
      };
          
      person.greet(); // 'hello';
          
      // 위 예제와 완전히 똑같이 동작합니다.
      const person = {
        greet() {
          return 'hello';
        }
      };
          
      person.greet(); // 'hello';
      
    • 메소드를 사용하면 데이터와 데이터에 관련된 동작을 객체라는 하나의 단위로 묶어서 다룰 수 있다. => 객체 지향 프로그래밍

    • prototype을 이용해 메소드를 직접 넣을 수 있다.

      Person.prototype.getOlder = function() {
          this.age++;
      }
      
  • this

    • this 키워드를 사용하면, 메소드 호출 시에 해당 메소드를 갖고 있는 객체에 접근할 수 있다.
    • 함수 내부의 this 키워드가 실제로 무엇을 가리킬 것인가는, 메소드가 어떻게 정의되는가에 의해 결정되는 것이 아니라 메소드가 어떻게 사용되는가에 의해 결정된다.
    • 어떤 객체의 메소드로 사용되느냐에 따라 메소드 내부의 this 가 가리키는 객체가 달라질 수 있다.
    function introduce() {
      return `안녕하세요, 제 이름은 ${this.name}입니다.`;
    }
      
    const person1 = {
      name: '윤아준',
      introduce
    };
      
    const person2 = {
      name: '신하경',
      introduce
    };
      
    person1.introduce(); // 안녕하세요, 제 이름은 운아준입니다.
    person2.introduce(); // 안녕하세요, 제 이름은 신하경입니다.
    
    • 화살표 함수에서는 this 의 작동방식이 아예 다르다.
  • 생성자 (Constructor)

    • 객체를 만들 때 new 키워드와 함께 사용하는 함수를 생성자라고 부른다.

      const obj = new Object();
      
    • 생성자 정의하기

      // 생성자 정의
      function Person(name) {
        this.name = name;
      }
          
      // 생성자를 통한 객체 생성
      const person1 = new Person('윤아준');
      
      • function 구문을 통해 Person 이라는 생성자를 정의하고, 생성자 안에서는 this 키워드를 사용해서 새로 만들어질 객체의 속성을 지정해 준다.
      • new 키워드를 사용해서 객체를 생성하는 순간에 생성자 안에 있는 코드가 실행되어 객체의 속성이 지정된다.
      • 생성자는 대문자로 시작하게끔 이름을 짓는 것이 관례.
    • 인스턴스 (Instance)

      • 생성자를 통해 생성된 객체를 그 생성자의 인스턴스라고 한다.

      • instanceof 연산자를 사용하면, 객체가 특정 생성자의 인스턴스가 맞는지를 확인할 수 있다.

        person1 instanceof Person;	// true
        
      • 객체 리터럴을 통해 생성된 객체는 Object의 인스턴스이다.

        const obj = {};
        obj instanceof Object;	// true
        
    • 생성자와 일반적인 함수의 차이는 없다. 사용하기 나름. 이 부분은 자바스크립트의 부족한 점.

      • ES2015 에서 생긴 객체를 만들어내는 역할만 하는 생성자가 Class 이다.

배열 (Array)

  • 배열은 객체의 일종이지만, 내부적으로 특별하게 취급되어 일반적인 객체들과는 다른 특징을 갖는다.

  • 객체와 배열의 가장 큰 차이점은, 배열의 요소 간에는 순서가 있다는 점이다. 객체의 요소 간에는 순서가 없다.

  • 배열은 Array 생성자의 인스턴스이다. 따라서 배열의 프로토타입으로 Array.prototype 객체가 지정되어 있다. 이 객체에 저장된 많은 메소드를 활용해 배열을 조작할 수 있다.

  • 배열 생성하기

    • 배열 리터럴

    • Array 생성자

      • 인수가 어떻게 들어오는지에 따라 동작 방식이 다르기 때문에 일관적이지 않다. (잘 안씀)
    • Array.of 정적 메소드

      • Array 생성자의 단점을 보완하기 위해 ES2015에서 등장. (리터럴보다 불편해서 잘 안씀)
      new Array(1, 2, 3); // 이렇게 하지 마세요!
      Array.of(1, 2, 3) // 대신 이렇게 하세요.
          
      // `Array.of` 정적 메소드는 인수가 하나이더라도 그 인수를 요소로 갖는 배열을 반환합니다.
      Array.of(1); // [1]
          
      // 생성자는 이런 용도로만 사용하세요.
      new Array(1000); // [empty × 1000]
      
    • Array.from 정적 메소드

      • 자바스크립트의 유사 배열 객체(array-like object)와 iterable이라는 개념 때문에, 이에 해당하는 값들을 Array.from 정적 메소드를 통해 배열로 변환할 수 있다.
      // `string` 타입은 래퍼 객체를 통해 iterable로 다루어질 수 있습니다.
      Array.from('hello'); // ["h", "e", "l", "l", "o"]
      
  • 배열의 끝 부분에서 요소를 추가/제거하기

    • arr.push()
    • arr.pop()
      • pop() 메소드는 배열에서 맨 마지막 요소를 꺼내면서 그 값을 반환값으로 갖는다.
      • pop()을 계속해서 배열에 더이상 요소가 없다면 ‘undefined’ 를 반환한다.
  • 배열의 시작 부분에서 요소를 추가/제거하기

    • arr.unshift()
    • arr.shift()
  • 요소를 배열 중간에 삽입하기

    • arr.splice(index, quantity, [elements...])
      • index 번째 요소부터 quantity 개를 elements로 바꿔치기 한다. (반드시 같은 개수의 요소만 바꿔치기 할 수 있는 것은 아니다.)
      • 새 요소로 바꿔치기 하고, 바꿔치기 당한 기존 요소들을 반환값으로 갖는다.
      • [elements…] 인수를 생략하면 요소를 제거한다.
      • quantity를 0으로 하면 요소를 추가하는 것도 가능하다.
  • 배열 뒤집기

    • arr.reverse()
  • 배열 정렬하기

    • arr.sort(function)
    • 인수로 비교 함수를 넘겨주고, 그 조건에 따라서 값이 정렬된다.
    • 비교함수 작동방법
      • 만약 어떤 두 값 a, b에 대해서 비교 함수 comparecompare(a, b) 와 같이 호출했을때 :
        • 음수를 반환하면 a가 b 앞에 오도록 정렬한다.
        • 0을 반환하면 a와 b를 같은 순서로 간주한다.
        • 양수를 반환하면 b가 a 앞에 오도록 정렬한다.
    • 인수로 비교함수를 넣지 않으면 sort 메소드는 먼저 요소를 전부 문자열로 변환한 후, 유니코드 코드포인트를 비교하는 방식으로 정렬한다.
    • 문자열을 사전순으로 정렬하려면 x.localeCompare(y) 로 비교함수를 넘겨준다.
  • 배열 순회하기

    • for 구문

    • forEach 메소드 - ES5

      • 배열의 각 요소에 대해 함수를 호출할 수 있다.
      const arr = [1, 2, 3];
      arr.forEach((item, [index], [array]) => {
        console.log(`현재 ${index + 1}번째 요소에 대해 함수가 실행되고 있습니다.`);
      });
          
      // item은 현재 순회중인 배열의 요소
      // index는 요소의 인덱스
      // array는 순회중인 배열
      
    • for...of 구문 - ES2015

      • Iterable 구문을 순회하기 위해 사용한다. (배열도 Iterable이기 때문에 배열에 사용 가능)
      • 배열의 인덱스가 필요한 경우에는 forEach 메소드나 for 구문을 사용해야 한다.
      const arr = [1, 2, 3, 4, 5];
          
      for (let item of arr) {
        console.log(item);
      }
          
      // 변수 item을 매번 새로 만들고, 변수가 블록 스코프이기 때문에 for문 안에서만 유효하다. 따라서 let이 아니라 const로 선언해도 작동한다.
      
  • 배열로부터 새로운 값 생성 (원본 배열 조작 X, 새로운 배열 생성 O)

    • slice

      • 배열의 일부분에 해당하는 새로운 배열을 반환한다.
      • arr.slice([index, index])
      • 첫 번째 인수의 default===0, 두 번째 인수의 default===arr.length 이기 때문에 인수 없이 호출하면 배열 전체가 복사된다.
      • slice는 얕은 복사(shallow copy)를 하기 때문에, 배열 안에 배열 또는 객체가 들어있을 때는 주의해서 사용해야 한다.
    • map

      • 배열의 각 요소에 함수를 적용해서 그 반환값을 요소로 갖는 새로운 배열을 만든다.
      const arr = [1, 2, 3, 4, 5];
          
      arr.map((item, [index], [array]) => {
        return item * index;
      }); // [0, 2, 6, 12, 20]
      
    • concat

      • 여러 배열을 연결해서 하나의 새 배열을 만든다.
    • reduce

      • 모든 요소의 값을 종합해서 하나의 값으로 만드는 계산을 할 때 사용한다.
    • filter

      • 원하는 요소만을 골라내어 새로운 배열을 생성한다.
      • 메소드의 인수에는 진리값(boolean)을 반환하는 함수(predicate)를 주어야 한다.
      • 진리값을 반환하는 함수는 (현재 요소, 인덱스, 배열) 세 인수를 받는다.
    • join

      • 배열의 요소들을 문자열로 변환한 후, 메소드의 인자로 주어진 구분자(seperator)를 이용해 하나의 문자열로 결합해서 반환한다.
      • 구분자를 넘기지 않으면 default로 , 가 사용된다.
    • 요소 찾기

      • indexOf : 배열의 왼쪽부터 검색해서 처음 만나는 요소의 인덱스를 반환한다.
      • lastIndexOf : 배열의 오른쪽부터 검색
      • 요소를 찾지 못하면 -1 을 반환한다.
      • find : predicate를 이용해 왼쪽부터 검사해서 처음 만나는 요소를 찾는다.
        • find 메소드는 요소 자체를 반환한다.
        • 못찾으면 undefined 를 반환.
        • predicate 에는 (현재 요소, 인덱스, 배열) 세 인수를 넘길 수 있다.
      • findIndex : predicate를 이용해 왼쪽부터 검사해서 처음 만나는 요소를 찾는다.
        • findIndex는 요소의 인덱스를 반환한다.
        • 못찾으면 -1 을 반환.
        • predicate 에는 (현재 요소, 인덱스, 배열) 세 인수를 넘길 수 있다.
    • 배열이 특정 조건을 만족하는지 판별하기 (return true   false)
      • includes : 배열이 특정 요소를 포함하고 있는지를 판별한다.
      • every : predicate를 인수로 받아서 모든 요소가 조건을 만족하는지를 검사한다.
      • some : predicate를 인수로 받아서 조건을 만족하는 요소가 하나라도 있는지 검사한다.
    • 배열인지 아닌지 판별하기

      • Array.isArray(item);
    • 다차원 배열 (Multidimensional Array)

      • 배열 속에 배열이 중첩되어 있는 자료 구조
      const table = [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
      ];
          
      table[0][1]; // 2
      table[2][0]; // 7
      

댓글남기기