프로그래머에게 프로그래밍의 관점을 갖게하고 결정하는 역할을 한다
명령형 프로그래밍: 프로그래밍의 상태와 상태를 변경시키는 구문의 관점에서 연산을 설명하는 방식
선언형 프로그래밍: 어떤 방법으로 해야 하는지(How)를 나타내기보다 무엇(What)과 같은지를 설명하는 방식
→ 자바스크립트에서 함수(Function)은 객체(Object)이므로 1급 함수로 불린다.
→ 고차 함수는 1급 함수의 부분 집합(Subset)이다.리액트의 고차 컴포넌트(HOC)는 컴포넌트를 사용하여 위의 조건을 만족하는 컴포넌트를 말한다.
// 불변이 아닌 변하는(Mutatable) 데이터
function rateColor(color, rating) {
color.rating = rating;
return color;
}
console.log(rateColor(color_lawn, 5), rating) // 5
console.log(color_lawn.rating) // 5
// 불변성 데이터
function rateColor(color, ratring) {
return Object.assign({}, color, {ratring:ratring});
}
console.log(rateColor(color_lawn, 5), rating) // 5
console.log(color_lawn.rating) // 0 *변하지 않음*
→ const 키워드와 불변은 구분해야 한다. const는 Object로 사용되는 경우 변경 가능하다.
→ 순수 함수를 호출하면 프로그램의 어떠한 변화도 없고, 입력 값에 대한 결과를 예상할수 있어서 테스트하기가 쉽다.
// 순수하지 않은 함수, DOM을 변경하는 부수효과를 발생시킴
function Header(text) {
let h1 = document.createElement('h1');
h1.innerText = text;
document.body.appendChild(h1);
}
// 순수한 함수, 부수효과를 발생시키지 않음
// DOM을 변경하는 책임은 애플리케이션의 다른 부분이 담당하도록 한다.
const Header = (props) => <h1>{props.title}</h1>
함수형 프로그래밍은 순수 함수(pure function) 를 조합하고 공유 상태(shared state), 변경 가능한 데이터(mutable data) 및 부작용(side-effects) 을 피하여 소프트웨어를 만드는 프로세스다. 함수형 프로그래밍은 명령형(imperative) 이 아닌 선언형(declarative) 이며 애플리케이션의 상태는 순수 함수를 통해 전달된다.
객체 지향 프로그래밍은 함수들의 집합 혹은 단순한 컴퓨터의 명령어들의 목록이라는 기존의 프로그래밍에 대한 전통적인 관점에 반하여, 컴퓨터 프로그램을 객체들의 모임으로 파악하고자 하는 프로그래밍 패러다임 중 하나입니다.
객체 지향 프로그래밍은 클래스를 이용해 연관 있는 처리 부분(함수)과 데이터 부분(변수)를 하나로 묶어 객체(인스턴스)를 생성해 사용합니다. 객체 지향 프로그래밍에서 각 개체는 메시지를 받을 수 있고, 데이터를 처리할 수 있으며, 또 다른 객체에 메시지를 전달할 수 있습니다. 즉, 각 객체를 별도의 역할이나 책임을 갖는 작은 독립적인 기계로 볼 수 있습니다.
자식 클래스에서 부모 클래스의 기능을 재정의할 때 사용하는 기능입니다.
오버라이딩은 두 가지 경우에 주로 사용합니다.
1) 부모 클래스의 기능을 사용하지 않고 자식 클래스에서 구현한 기능을 사용하고 싶은 경우
부모의 기능을 직접 수정하지 않고, 부모의 기능을 재정의할 때 오버라이딩을 사용합니다.
MyParent.prototype.부모메소드 = function() {}
MyChild.prototype.부모메소드 = function() {}
function MyParent() {
this.property1 = 'data1';
console.log('MyParent');
}
MyParent.prototype.method1 = function() {
console.log('property1= ' + this.property1);
}
function MyChild() {
console.log('MyChild');
}
//부모 클래스 상속
MyChild.prototype = new MyParent();
//생성자 설정
MyChild.prototype.constructor = MyChild;
//오버라이딩
MyChild.prototype.method1 = function() {
console.log('프로퍼티 1은 '+ this.property1+' 입니다.');
}
//자식 인스턴스 생성
let child = new MyChild();
//메소드 호출
child.method1();
//console 출력 결과
//MyParent
//MyChild
//프로퍼티 1은 data1 입니다.
부모 클래스의 method1()는 더이상 동작하지 않고, 자식 클래스의 method1()이 동작하는 것을 확인할 수 있습니다.
2) 부모 클래스의 기능을 자식 클래스에서 확장하고 싶은 경우
부모의 기능을 완전히 새롭게 재정의하는 것이 아니라 부모의 기능을 그대로 사용하면서 기능을 약간 추가하고 싶은 경우가 있습니다. 이 경우에 오버라이딩을 사용합니다.
//부모 클래스
function MyParent() {
this.property1 = '문자열 데이터';
console.log('MyParent()');
}
MyParent.prototype.info = function() {
console.log('property1= '+ this.property1);
}
//자식 클래스
function MyChild() {
console.log('MyChild()');
this.property2 = '데이터';
}
//부모 클래스 상속
MyChild.prototype = new MyParent();
//생성자 설정
MyChild.prototype.constructor = MyChild;
//확장할 기능인 info를 자식 클래스에서 오버라이딩
MyChild.prototype.info = function() {
MyParent.prototype.info.call(this); //call()을 이용해 부모 클래스의 info()메소드 호출
console.log('프로퍼티 2는 '+this.propert2+' 입니다.')
};
//자식 인스턴스 생성
let child1 = new MyChild();
//자식 정보 출력
child1.info(); //프로퍼티 2는 데이터 입니다.
동일한 이름을 가진 여러 개의 메소드를 만든 후 매개변수 타입과 개수에 맞는 메소드가 자동으로 호출되는 기능을 말합니다. 자바스크립트는 자료의 타입을 선언하지 않기 때문에 오버로딩을 제공하지 않습니다.
- 명령형: 프로그램은 명령의 수행이다.
- 함수형: 프로그램은 함수의 계산이다.
- 명령형: 어떻게 (how to) 에 초점
- 함수형: 무엇(what)에 초점
- 명령형: 튜링 머신
- 함수형: 람다 계산식
- 명령형: C, 자바 등 대부분의 언어
- 함수형: Scheme, Haskel
class BankAccount {
constructor(balance) {
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
}
withdraw(amount) {
if (amount > this.balance) {
console.log("Insufficient funds");
} else {
this.balance -= amount;
}
}
}
let account = new BankAccount(100);
account.deposit(50);
console.log(account.balance); // 150
account.withdraw(75);
console.log(account.balance); // 75
const deposit = (balance, amount) => balance + amount;
const withdraw = (balance, amount) => {
if (amount > balance) {
console.log("Insufficient funds");
return balance;
}
return balance - amount;
};
let balance = 100;
balance = deposit(balance, 50);
console.log(balance); // 150
balance = withdraw(balance, 75);
console.log(balance); // 75