Skip to content

객체와 클래스

iforget edited this page May 1, 2020 · 1 revision

배열과의 차이점

  • 배열은 인덱스가 숫자, 객체는 인덱스가 문자열이나 Symbol
  • 배열은 순서가 보장됨. 객체는 프로퍼티들 간에 순서가 보장 x

프로퍼티 나열

for...in

  • 객체의 프로퍼티 키로 루프를 실행하도록 설계
  • 키가 심볼인 프로퍼티는 루프에 포함되지 않는다.
  • 키를 문자값으로 열거
const SYM = Symbol();
 
const o = {a: 1, b: 2, c: 3, [SYM]: 4};
 
for(let prop in o){
    if(o.hasOwnProperty(prop)){
        console.log(`${prop} : ${o[prop]}`);
    }
}
 
/* result
a : 1
b : 2
c : 3
*/
    • 배열에는 사용하지 말자
let scores = [98, 74, 85, 77, 93, 100, 89];
let total = 0;
for (let i in scores){
    total += i;
}
console.log(total); // '00123456'

for...of loop

  • 배열과 이터러블 객체에 모두 사용할 수 있는 반복문(ES6)
let scores = [98, 74, 85, 77, 93, 100, 89];
let total = 0;
for (let i of scores){
    total += i;
}
console.log(total); // 616

Object.keys

  • 객체의 프로퍼티 키를 배열로 반환
  • 키가 심볼인 프로퍼티는 루프에 포함되지 않는다.
  • hasOwnProperty() 로 체크할 필요 없음
const SYM = Symbol();
 
const o = {a: 1, b: 2, c: 3, [SYM]: 4};
 
Object.keys(o).forEach(prop => console.log(`${prop} : ${o[prop]}`));
  
/* result
a : 1
b : 2
c : 3
*/

클래스 문법

특징

  • 생성자와 상속을 좀더 간단하고 명확하게 다룰 수 있게 ES6에 추가된 구문
  • 클래스도 함수. 단축 문법일 뿐 자체가 바뀐 것은 아님
  • 클래스 바디 안에 있는 메서드는 모두 클래스 prototype 프로퍼티에 추가된다.
class Person {
    constructor(){
    }
}
 
class Car {
    contructor(make, model){
        this.make = make;
        this.model = model;
        this.userGears = ['P', 'N', 'R', 'D'];
        this.userGear = this.userGears[0];
    }
 
    shift(gear){
        if(this.userGears.indexOf(gear) < 0 ){
            throw new Error(`Invalid gear: ${gear}`);
        }
        this.userGear = gear;
    }
}
 
const car = new Car('Tesla', 'Model S');
car.shift('D');

get/set 메서드

  • 메서드 앞에 get, set을 붙여서 접근자 프로퍼티의 get/set 속성 정의할 수 있음
class Person{
    constructor(name){
        this._name = name;
    }
 
    get name(){
        return this._name;
    }
 
    set name(name){
        this._name = name;
    }
}
 
let p = new Person('Tom');
console.log(p.name);
p.name = 'Brad';
console.log(p.name);

Prototype의 동적 디스패치

  • 객체의 프로퍼티나 메서드에 접근할때 접근하는 요소에 없으면 프로토타입에서 찾는다.
  • 인스턴스에서 메서드나 프로퍼티를 정의하면 프로토타입에 있는 것을 가려버린다
class Car {
    contructor() {
        this.userGears = ['P', 'N', 'R', 'D'];
        this.userGear = this.userGears[0];
    }
 
    shift(gear) {
        if (this.userGears.indexOf(gear) < 0) {
            throw new Error(`Invalid gear: ${gear}`);
        }
        this.userGear = gear;
    }
}
 
const car1 = new Car();
const car2 = new Car();
 
car1.shift === Car.prototype.shift; //true
car1.shift('D');
car1.shift('d'); //Error
car1.userGear; //'D'
car1.shift === car2.shift; //true
 
car1.shift = function (gear) {
    this.userGear = gear.toUpperCase();
};
car1.shift === Car.prototype.shift //false
car1.shift === car2.shift; //false
car1.shift('d');
car1.userGear; //'D'

정적 메서드

  • 클래스 바디 안의 메서드명 앞에 static을 붙임
  • prototype 프로퍼티가 아닌 클래스 자체의 메소드를 생성
  • 주로 유틸리티 함수작성에 사용
class Student {
    constructor(name){
        this.name = name;
    }
 
    static findName(student){
        return student.name;
    }
}
 
const s1 = new Student('a');
const s2 = new Student('b');
 
console.log(Student.findName(s1)); //a
console.log(Student.findName(s2)); //b

상속

  • extends와 super를 이용
  • 프로토타입 체인 : 객체의 프로토타입에서 메서드를 찾지 못하면 자바스크립트는 프로토타입의 프로토타입을 검색
class Vehicle{
    constructor(){
        this.passengers = [];
        console.log('Vehicle created');
    }
    addPassenger(p){
        this.passengers.push(p);
    }
}
 
class Car extends Vehicle{
    constructor(){
        super();
        console.log('Car created');
    }
    deployAirbags(){
        console.log('BWOOSH!');
    }
}
 
const v = new Vehicle();
v.addPassenger('Frank');
v.addPassenger('Judy');
v.passengers; // ['Frank', 'Judy']
 
const c = new Car();
c.addPassenger('Alice');
c.addPassenger('Cameron');
c.passengers; // ['Alice', 'Cameron']
 
v.deployAirbags();//error

호이스팅 불가

new MyFunc();
function MyFunc(){ }
 
new MyClass(); //ReferenceError: MyClass is not defined
class MyClass{}