객체 지향적 프로그래밍 (Object Oriented Programming)은 데이터가 객체 내에 캡슐화되고 구성 요소 부분이 아닌 객체 자체가 운용되는 프로그래밍 방식.
new
연산자와 생성자 함수를 사용하면 유사한 객체 여러 개를 쉽게 만들 수 있다.
생성자 함수(constructor function)와 일반 함수에 기술적인 차이는 없다.
'new'
연산자를 붙여 실행.function User(name) {
this.name = name;
this.isAdmin = false;
}
let user = new User("비트");
alert(user.name); // 비트
alert(user.isAdmin); // false
new User(...)
를 써서 함수를 실행하면 아래와 같은 알고리즘이 동작
this
에 할당.this
에 새로운 프로퍼티를 추가해 this
를 수정 )this
를 반환this
생성자 함수 해설위 예시를 통해 this
를 알아보자.
// new User(...)가 실행되면,
function User(name) {
// this = {}; (빈 객체가 암시적으로 만들어짐)
// 새로운 프로퍼티를 this에 추가함
this.name = name;
this.isAdmin = false;
// return this; (this가 암시적으로 반환됨)
}
이제 let user = new User("비트")
는 아래 코드를 입력한 것과 동일하게 동작.
let user = {
name: "비트",
isAdmin: false
};
new User("비트")
이외에도 손 쉽게 사용자 객체를 만들 수 있다.
객체 리터럴 문법으로 일일이 객체를 만드는 방법보다 간단하고 쉬우며, 재사용할 수 있는 객체 생성 코드를 구현한다.
재사용할 필요가 없는 복잡한 객체를 만들어 보자.
익명 생성자 함수
로 감싸주는 방식을 사용할 수 있다.
let user = new function() {
this.name = "비트";
this.isAdmin = false;
// 사용자 객체를 만들기 위한 여러 코드.
// 지역 변수, 복잡한 로직, 구문 등의
// 다양한 코드가 여기에 들어간다.
};
Class
클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀로, 객체를 정의하기 위한 상태(멤버 변수)와 메서드(함수)로 구성된다.
class
선언은 프로토타입 기반 상속을 사용하여, 주어진 이름의 새로운 클래스를 만든다.
Class
기본문법class MyClass {
// 여러 메서드를 정의할 수 있음
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
// 이렇게 클래스를 만들고, new MyClass()를 호출하면
// 내부에서 정의한 메서드가 들어 있는 객체가 생성
객체의 기본 상태를 설정해주는 생성자 메서드 constructor()
는 new
에 의해 자동으로 호출되므로, 특별한 절차 없이 객체를 초기화 할 수 있다.
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// 사용법:
let user = new User("비트");
user.sayHi(); // 비트
new User("비트")
를 호출하면?
이렇게 user.sayHi()
같은 객체 메서드를 호출할 수 있다.
메서드 사이엔 쉼표를 표기하지 않는다.
쉼표를 넣으면 문법 에러가 발생. 따라서, 클래스에선 메서드 사이에 쉼표를 넣지 않아도 된다.
자바스크립트에서 클래스는 함수의 한 종류이다.
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// User가 함수라는 증거
alert(typeof User); // function
class User {...}
문법 구조
User
라는 이름을 가진 함수를 만든다.constructor
에서 가져온다.User.prototype
에 저장함수처럼 클래스도 다른 표현식 내부에서 정의, 전달, 반환, 할당할 수 있다.
let User = class {
sayHi() {
alert("안녕하세요.");
}
};
기명 함수 표현식 유사하게 클래스 표현식에도 이름을 붙일 수 있지만, 그럴 경우 오직 클래스 내부에서만 사용할 수 있다.
let User = class MyClass {
sayHi() {
alert(MyClass); // MyClass라는 이름은 오직 클래스 안에서만 사용할 수 있다.
}
};
new User().sayHi(); // 원하는대로 MyClass의 정의를 보여준다.
alert(MyClass);
// ReferenceError: MyClass is not defined,
// MyClass는 클래스 밖에서 사용할 수 없다.
필요에 따라 클래스를 동적으로 생성하는 것도 가능하다.
function makeClass(phrase) {
// 클래스를 선언하고 이를 반환함
return class {
sayHi() {
alert(phrase);
};
};
}
// 새로운 클래스를 만듦
let User = makeClass("안녕하세요.");
new User().sayHi(); // 안녕하세요.
getter와 setter
리터럴을 사용해 만든 객체처럼 클래스도 getter
나 setter
, 계산된 프로퍼티(computed property)를 지원한다.
class User {
constructor(name) {
// setter를 활성화합니다.
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("이름이 너무 짧습니다.");
return;
}
this._name = value;
}
}
let user = new User("비트");
alert(user.name); // 비트
user = new User(""); // 이름이 너무 짧습니다.
// getter와 setter는 User.prototype에 정의된다.
클래스 필드(class field)
라는 문법을 사용하면 어떤 종류의 프로퍼티도 클래스에 추가할 수 있다.
class User {
name = "비트";
sayHi() {
alert(`${this.name}님 안녕하세요!`);
}
}
new User().sayHi(); // 비트님 안녕하세요!
클래스를 정의할 때 <프로퍼티 이름> = <값>
을 써주면 간단히 클래스 필드를 만들 수 있다.
class User {
name = "비트";
}
let user = new User();
alert(user.name); // 비트
alert(User.prototype.name); // undefined
// User.prototype가 아닌 개별 객체에만 클래스 필드가 설정된다.
클래스 필드엔 복잡한 표현식이나 함수 호출 결과를 사용 할 수 있다.
class User {
name = prompt("이름을 알려주세요.", "비트");
}
let user = new User();
alert(user.name); // 비트
Abstraction
)복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화한다.
Inheritance
)불필요한 코드를 줄여 재사용성을 높인다.
Polymorphism
)동일한 메서드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해진다.
Encapsulation
)코드가 복잡하지 않게 만들고, 재사용성을 높인다.
JavaScript는 프로토타입(Prototype) 기반 언어
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
sleep() {
console.log(`${this.name}은 잠에 들었습니다`);
}
}
let kimcoding = new Human('김코딩', 30);
// 실습해보세요
Human.prototype.constructor === Human;
Human.prototype === kimcoding.__proto__;
Human.prototype.sleep === kimcoding.sleep;
// Human 클래스의 sleep 메서드는 프로토타입에 있으며,
// Human 클래스의 인스턴스인 kimcoding에서
// kimcoding.sleep으로 사용할 수 있다.