스터디/개인스터디

#010 자바스크립트 200제 - Arrow function, 객체지향 프로그래밍, 생성자 함수, 클래스 정의

d0201d 2020. 12. 11. 22:19

화살표함수(Arrow function)

- ES6부터 나온 문법으로 기존 함수를 간결하게 표현할수 있음

//매개변수가 하나일 경우, 인자를 정의할때 괄호 생략 가능
const double = x => x + x;
console.log(double(2)); //4

//매개변수가 둘이상일때 괄호 작성
const add = (a, b) => a + b;
console.log(add(1, 2)); //3

//매개 변수가 없을때 괄호 작성
const printArguments = () => {
    console.log(arguments);
}
printArguments(1, 2, 3); // arguments객체가 없기 때문에 Error

//함수 코드 블럭을 지정햇을때 반환하고자 하는 값에 return문 작성
const sum = (...args) => {
    let total = 0;
    for (let i = 0; i < args.length; i++) {
        total += args[i]
    }
    return total;
}
console.log(sum(1, 2, 3)); //6

//함수 코드 블럭을 지정하지 않고 한문장으로 작성 시 return문을 사용하지 않아도 결과값이 반환됨
setTimeout(() => {
    console.log('Arrow Function!')  //Arrow Function!
}, 10);

 

객체지향 프로그래밍

- 프로그램을 객체들로 구성하고 객체들 간에 서로 상호작용을 하도록 작성하는 방법

- 객체는 특징적인 행동변경가능한 상태를 가짐

- 객체지향에서는 협력하지 않는 객체는 없음

- 객체지향에서는 객체들이 서로 의사소통을 하며 메소드를 통해 서로 메세지를 전달함

// 제이는 이름과 나이를 속성으로 가지고 있고 자바스크립트를 가르치는 행위를 함
const teacherJay = {
    name: "제이",  
    age: 30,
    teachJavascript: function(student) {  // teacherJay객체는 student객체를 사용 
        student.gainExp();
    }
}

//학생은 이름과 나이 그리고 경험티를 가지고 있고 경험치를 얻는 행위를 함
const studentBbo = {
    name: "학생",
    age: 20,
    exp: 0,
    gainExp: function() {
        this.exp++;
    }
}

console.log(studentBbo.exp); //0
teacherJay.teachJavascript(studentBbo);
console.log(studentBbo.exp); //1;

 

- 자바스크립트는 포로토타입 기반으로 객체지향 프로그래밍을 지원함(객체에 공통사항을 적용할수 있음)

- 즉, 모든 객체는 다른 객체의 프로토타입(원형)이 될수 있음

- 특징을 묘사하는 포로토타입을 만들고 그 프로토 타입에 기반하는 여러 객체들을 만들면 모두 같은 특징을 가질수 있음

// 학생의 경험치를 얻는 행위를 하나의 메소드로 작성한 포로토 타입을 정의
const studentProto = {
    gainExp: function() {
        this.exp++;
    }
}

const harin = {
    name: '하린',
    age: 10,
    exp: 0,
    __proto__: studentProto
};

const bbo = {
    name: "나나",
    age: 20,
    exp: 10,
    __proto__: studentProto
};

bbo.gainExp(); //10
harin.gainExp(); //1
harin.gainExp(); //2
console.log(harin); // {name: "하린", age: 10, exp: 2}
console.log(bbo); // {name: "나나", age: 20, exp: 11}

 

생성자함수

- 객체를 생성할 때 사용하는 함수

function Teacher(name, age, subject) {
    this.name = name;
    this.age = age;
    this.subject = subject;
    this.teach = function(student) {
        console.log(student + '에게' + this.subject + '를 가르쳐드립니다.')
    }
}

//new 키워드와 함께 생성자 함수를 호출
const jay = new Teacher('jay', 30, 'Javascript');
console.log(jay); // VM232:11 Teacher {name: "jay", age: 30, subject: "Javascript", teach: ƒ}
jay.teach('bbo'); //bbo에게Javascript를 가르쳐드립니다.

console.log(jay.constructor); // ƒ Teacher(name, age, subject) { ...}
console.log(jay instanceof Teacher) // true (jay객체가 Teacher 생성자 함수의 인스턴스 여부 )

//new 키워드를 빼고 생성자 함수를 호출
const jay2 = Teacher('jay', 30, 'Javascript'); //this의 전역객체를 가르킴
console.log(jay2); // undefinded (새로운 객체가 반환되지 않았기 때문에)
console.log(age); // 30

- new 키워드와 함께 생성자 함수를 호출하면 생성자 함수 블록이 실행되고 별도의 return없이 객체반환 

- constructor 속성은 개체를 만든 생성자 함수를 가리킴

 

 

포로토타입 기반 상속

- 생성자 함수로부터 만들어진 객체는 그 생성자 함수의 포로토타입 객체를 상속

- 즉, 모든 인스턴스는 해당 생성자함수의 프로토타입 객체의 속성과 메소드를 사용할수 있음.

function Storage() {
    this.dataStore = {};
}

//생성자 함수의 프로토타입 객체에 put 메소드 추가
Storage.prototype.put = function(data, key) {  
    this.dataStore[key] = data;
}
//생성자 함수의 프로토타입 객체에 getData 메소드 추가
Storage.prototype.getData = function(key) {
    return this.dataStore[key];
}

//Storage 타입의 인스턴스 생성 (Storage 함수의 프로토 타입에 정의된 메소드들을 사용가능해짐 )
const productStorage = new Storage();
productStorage.put('id001', { name: '키보드', price: 2000 });
console.log(productStorage.getData('id001'))

function RemovableStorage() {
    Storage.call(this);
}

RemovableStorage.prototype = Object.create(Storage.prototype);  
RemovableStorage.prototype.removeAll = function() {
    this.dataStore = {}
}

const productStorage2 = new RemovableStorage();
productStorage2.put('id001', { name: '키보드', price: 2000 });
productStorage2.removeAll();
const item2 = productStorage2.getData('id001');
console.log(item2);

- Object.create 메소드는 주어인 인자를 __proto__에 연결한 새로운 객체를 반환(간단히 상속관계를 형성할수 있음)

 

 

클래스 정의

- 클래스를 통해 객체가 가져야할 상태와 행위들을 속성과 메소드를 정의할수 있음

- 특정 클래스를 통해 만들어진 객체는 해당 클래스의 인스턴스

//CALSS 키워드를 이용해서 Cart 클래스를 정의
class Cart {
    constructor() {
        this.store = {};
    }

    addProduct(product) {
        this.store[product.id] = product;
    }

    getProduct(id) {
        return this.store[id];
    }
}

const cart1 = new Cart();

cart1.addProduct({ id: 50, name: '노트북' })
console.log(cart1.store); //{50: {id: 50, name: '노트북'}}

const p = cart1.getProduct(50);
console.log(p); // {id: 50, name: '노트북'}

 

클래스 상속

- 클래스 상속은 extends 키워드를 사용

- super 키워드로 부모 생성자 함수를 가르킴

class Chart {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }

    drawLine() {
        console.log('draw line')   //draw line
    }
}
//Chart 클래스를 상속하는 BarChart 클래스 정의
class BarChart extends Chart {
    constructor(width, height) {
        super(width, height)  //super 로 부모 생성자 함수를 가르킴
    }

    draw() {
        this.drawLine();
        console.log(`draw ${this.width} X ${this.height} BarChart`);  //draw 100 X 100 BarChart
    }
}

const barchart1 = new BarChart(100, 100);
barchart1.draw();