
그냥 다 처음 살아보는 인생이라서 서툰건데, 그래서 안쓰러운건데, 그래서 실수 좀 해도 되는데
오늘은 5시 40분에 기상하고 6시에 공부를 시작했다! 그래도 일어나는 시간이 5로 변하고 있어 행복하다.
항상 조금씩 초조해하지 말고 앞으로 나아가자!
클래스 기반의 객체지향 언어 - java
프로토타입 기반의 객체지향 언어 - javascript
// 예를 들어 작성하기
// Object Literal
const user = {
// 프로퍼티
email: 'jongmin@naver.com',
birthdate: '1992-03-21',
// 메소드
// this 는 user 를 나타낸다.
buy(item){
console.log(`${this.email} buys ${item.name}`);
},
}
const item = {
name: '스웨터',
price: 30000,
}
console.log(user.email);
console.log(user.birthdate);
user.buy(item)
유저를 한 명 더 추가해본다.
코드가 많이 길어지는 것을 확인 할 수 있다.
const user01 = {
email: 'jongmin@naver.com',
birthdate: '1992-03-21',
buy(item){
console.log(`${this.email} buys ${item.name}`);
},
}
const user02 = {
email: 'jjmin@naver.com',
birthdate: '1995-02-21',
buy(item){
console.log(`${this.email} buys ${item.name}`);
},
}
console.log(user01.email);
console.log(user01.birthdate);
user01.buy(item)
// Factory Function
function createUser(email, birthdate){
const user = {
email: email, // email
birthdate: birthdate, // birthdat
buy(item){
console.log(`${this.email} buys ${item.name}`);
},
}
return user;
}
const user1 = createUser('chris098@google.com', '1996-07-15');
const user2 = createUser('jerry@google.com', '1991-08-29');
console.log(user1);
console.log(user2);
user1.buy(item);
user2.buy(item);
function User(email, birthdate){
this.email = email;
this.birthdate =birthdate;
this.buy = function (item) {
console.log(`${this.email} buy ${this.name}`)
}
}
const item = {
name: '스웨터',
price: 10000,
}
const user1 = new User('chris098@google.com', '1990-08-19');
console.log(user1.email);
console.log(user1.birthdate);
user1.buy(item);
class ClassUser {
// 프로퍼티
constructor(email, birthdate){
this.email = email;
this.birthdate =birthdate;
}
// 메소드
buy(item){
console.log(`${this.email} buy ${item.name}`)
}
}
const user2 = new ClassUser('chris098@google.com', '1990-08-19');
console.log(user2.email);
console.log(user2.birthdate);
user2.buy(item);
class ClassUser {
constructor(email, birthdate){
this.email = email;
this.birthdate =birthdate;
}
buy(item){
console.log(`${this.email} buy ${item.name}`)
}
// setter 메소드
set email(address){
if (address.includes('@')){
this._email = address;
} else {
throw new Error('invalid email address');
}
}
// getter 메소드
get email() {
return this._email;
}
}
아래 코드를 보면 함수 외부에서 user1.email 로 _email 변수를 읽어오고 있다.
createUser 는 user1 객체를 를 생성하고 종료 되었지만 리턴된 객체에서 내부 변수(_email)를 읽어 올 수 있다.
이를 가능하게 하는 것은 자바스크립트의 클로저(Closure) 라고 하는 것 때문에 가능하다.
getter/setter 메소드를 갖고 있는 객체가 리턴된 이후더라도 여전히 내부 메소드들로 부모 메소드에 접근을 할 수 있게한다.(함수가 정의된 당시에 참조할 수 있었던 변수들을 계속 참조할 수 있는 상태의 함수를 클로저라고 한다.)
클로저란 자바스크립트에서 어떤 함수와 그 함수가 참조할 수 있는 값들로 이루어진 환경을 하나로 묶는 것을 의미한다.
function createUser(email, birthdate) {
let _email = email;
const user = {
birthdate,
get email() {
return _email;
},
set email(address) {
if (address.includes('@')) {
_email = address;
} else {
throw new Error('invalid email address');
}
},
};
return user;
}
const user1 = createUser('chris123@google.com', '19920321');
console.log(user1.email);
아래와 같이 작성하면 에러가 발생한다.
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
여기서 derived class 는 자식 클래스를 말한다.
자식클래스에서 super constructor 를 호출해야된다고 한다.
즉, 자식 클래스 생성자 함수 안에서 부모 클래스 생성자를 super 로 반드시 호출해야한다.
class User {
constructor(email, birthday){
this.email = email;
this.birthday = birthday;
}
buy(item){
console.log(`${this.email} buy ${item.name}`);
}
}
class PremiumUser extends User {
constructor(email, birthday, level){
this.level = level;
}
streamMusicForFree(){
console.log(`Free music streaming for ${this.email}`);
}
}
const item = {
name: '스웨터',
price: 10000,
}
const pUser1 = new PremiumUser('test@gmail.com', '1995-02-06');
console.log(pUser1.email);
console.log(pUser1.birthday);
console.log(pUser1.level);
class User {
constructor(email, birthday){
this.email = email;
this.birthday = birthday;
}
buy(item){
console.log(`${this.email} buy ${item.name}`);
}
}
class PremiumUser extends User {
constructor(email, birthday, level){
super(email, birthday);
this.level = level;
}
streamMusicForFree(){
console.log(`Free music streaming for ${this.email}`);
}
}
const item = {
name: '스웨터',
price: 10000,
}
const pUser1 = new PremiumUser('test@gmail.com', '1995-02-06');
console.log(pUser1.email);
console.log(pUser1.birthday);
console.log(pUser1.level);
class User {
constructor(email, birthday){
this.email = email;
this.birthday = birthday;
}
buy(item){
console.log(`${this.email} buy ${item.name}`);
}
}
class PremiumUser extends User {
constructor(email, birthday, level){
super(email, birthday);
this.level = level;
}
streamMusicForFree(){
console.log(`Free music streaming for ${this.email}`);
}
// 오버라이딩(overrindg)
buy(item){
console.log(`${this.email} buy ${item.name} with a 5 % discount`);
}
}
const item = {
name: '스웨터',
price: 10000,
}
const User1 = new User('userTest@gmail.com', '1992-02-06', 1);
const pUser1 = new PremiumUser('test@gmail.com', '1995-02-06', 3);
const users = [User1, pUser1];
users.forEach((user) => {
user.buy(item);
})
// User1.buy(item);
// pUser1.buy(item);
부모 클래스의 메소드가 필요하면?
super를 사용해서 호출하면 된다.
class User {
constructor(email, birthday){
this.email = email;
this.birthday = birthday;
}
buy(item){
console.log(`${this.email} buy ${item.name}`);
}
}
class PremiumUser extends User {
constructor(email, birthday, level, point){
super(email, birthday);
this.level = level;
this.point = point;
}
streamMusicForFree(){
console.log(`Free music streaming for ${this.email}`);
}
buy(item){
// console.log(`${this.email} buy ${item.name}`);
// 부모 클래스의 메소드를 그대로 사용하고 싶을 때도 super 를 호출할 수 있다.
super.buy(item);
this.point += item.price * 0.05;
}
}
const item = {
name: '스웨터',
price: 10000,
}
const User1 = new User('userTest@gmail.com', '1992-02-06', 1);
const pUser1 = new PremiumUser('test@gmail.com', '1995-02-06', 3);
const users = [User1, pUser1];
users.forEach((user) => {
user.buy(item);
})
users.forEach((user) => {
console.log(user instanceof PremiumUser);
}
// 부모 객체를 instanceof 하면 자식 객체에서도 true 가 나온다.
users.forEach((user) => {
console.log(user instanceof User);
}
class Math {
static PI = 3.14;
static getCircleArea(radius){
return Math.PI * radius * radius;
}
}