https://ko.javascript.info/class
클래스와 기본 문법
ko.javascript.info
클래스와 기본 문법
// 실무에선 사용자나 물건같이 동일한 종류의 객체를 여러 개 생성해야 하는 경우가 잦은데
// 이럴때 new 연산자와 생성자 함수에서 배운 new function을 사용할수 있다.
// 여기에 더하여 클래스(class)라는 문법을 사용하면 다양한 기능도 사용 가능하다.
class Button {
constructor (value){
this.value = value;
}
click(){
alert(this.value);
}
}
let a = new Button("sghasdg");
setTimeout(a.click,1000);

강사님이 알려주신 코드
new로 button 객체를 새로 생성하는데 this는 객체를 참조하니까
{키:값} 현재 new이니까 비어있는 상태이고
("sghasdg")이걸 넣었으니까 {value:sghasdg} 현재 이런 상태이다.
a : {value:sghasdg}
그 다음에 setTimeout(a.click,1000) 부분에서
setTimeout앞에는 원래 window가 붙는데 생략이 되었다. (window안에 setTimeout이 있음)
a.click 은
click 메서드의 결과값만 가져오고
ex) let b= 10; c=b? c=10이다.
window 안에는 setTimeout 이랑 결과값이 들어오는데
setTimeout의 첫번째 매개변수는 함수가 들어오는데 콜백함수 후에 실행이되고 결과값만 반환이 된다.
window 안에는 value이 없으니까 (this는 객체 참조) undefined가 뜬다.
위의 코드를 이해하고 나면 아래 코드를 이해할수 있다.(아래 코드를 해결해 보려면)
class Button {
constructor(value) {
this.value = value;
}
click() {
alert(this.value);
}
}
let button = new Button("안녕하세요.");
setTimeout(button.click, 1000); // undefined
아래는 수정된 코드
class Button {
constructor(value) {
this.value = value;
}
click = () => {
alert(this.value);
}
}
let button = new Button("안녕하세요.");
setTimeout(button.click, 1000); // 안녕하세요.
클래스 필드 click = () => {...}는 Button 클래스 내에 있는데
해당 클래스의 this를 참조하니까 결과가 제대로 나오게 됨
기본 문법
클래스는 다음과 같은 기본 문법을 사용해 만들수 있다.
class MyClass {
// 여러 메서드를 정의할 수 있음
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// 사용법:
let user = new User("John");
user.sayHi();
객체의 기본 상태를 설정해주는 생성자 메서드 constructor()는
new에 의해 자동으로 호출되므로,
특별한 절차 없이 객체를 초기화 할 수 있습니다.
클래스란
자바스크립트에서 클래스는 함수의 한 종류
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// User가 함수라는 증거
alert(typeof User); // function
클래스의 메서드가 프로토타입에 저장되고 공유된다??
말뜻이 어렵다. 아래 예제를 보고 이해해보자
class User { constructor(name) { this.name = name; } sayHi() { console.log(`Hello, ${this.name}!`); } }
여기서 User 클래스의 생성자 메서드는 this.name 속성을 초기화 한다.
이렇게 생성된 name 속성은 각 인스턴스의 고유한 값으로 사용된다.
sayHi() 메서드는 this.name 값을 사용하여 hello[이름]을 출력한다.
이 메서드는 User 클래스의 모든 인스턴스에서 호출할수 있으며
this.name 은 해당 인스턴스의 name 속성을 참조한다.
** 아래 코드는 위의 코드와 이어지는 코드다.
const user1 = new User('John'); const user2 = new User('Alice'); user1.sayHi(); // 출력: "Hello, John!" user2.sayHi(); // 출력: "Hello, Alice!"
이제 User 클래스의 인스턴스인 user1과 user2를 생성하고 각각의 sayHi() 메서드를 호출하면
hello [이름]이라는 메시지가 출력된다.
이때 sayhi() 메서드는 User.prototype에 저장되어 모든 User 객체에서 공유되는 메서드로 공유된다.
즉 클래스의 메서드는 프로토타입에 저장되어 인스턴스 간에 공유되며
이를 통해 메모리를 절약하고 메서드를 효율적으로 관리할수 있다.
이러한 개념은 프로그래밍에서 중요한 개념 중 하나이다.
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// User가 함수라는 증거
alert(typeof User); // function

class User {...} 문법 구조가 진짜 하는 일은 다음과 같다.
1. User라는 이름을 가진 함수를 만든다.
함수 본문은 생성자 메서드 constructor에서 가져온다. 생성자 메서드가 없으면 본문이 비워진 채로 함수가 만들어짐
2. sayHi 같은 클래스 내에서 정의한 메서드를 User.prototype에 저장한다.
// 클래스는 단순한 편의 문법이 아니다.
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// 클래스는 함수입니다.
alert(typeof User); // function
// 정확히는 생성자 메서드와 동일합니다.
alert(User === User.prototype.constructor); // true
// 클래스 내부에서 정의한 메서드는 User.prototype에 저장됩니다.
alert(User.prototype.sayHi); // alert(this.name);
// 현재 프로토타입에는 메서드가 두 개입니다.
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
// 클래스 내부에서 정의한 메서드는 User.prototype에 저장된다.
// class User와 동일한 기능을 하는 순수 함수를 만들어보겠습니다.
// 1. 생성자 함수를 만듭니다.
function User(name) {
this.name = name;
}
// 모든 함수의 프로토타입은 'constructor' 프로퍼티를 기본으로 갖고 있기 때문에
// constructor 프로퍼티를 명시적으로 만들 필요가 없습니다.
// 2. prototype에 메서드를 추가합니다.
User.prototype.sayHi = function() {
alert(this.name);
};
// 사용법:
let user = new User("John");
user.sayHi();
class 함수 이렇게 사용하면 오류뜬다.
class User {
constructor() {}
}
alert(typeof User); // User의 타입은 함수이긴 하지만 그냥 호출할 수 없습니다.
User();
- User는 클래스로 정의된 생성자 함수이다. => 이 이유 때문에 User() 이렇게만 호출하면 오류가 뜬다.
클래스는 함수 타입이기 때문에 typeof User 의 결과는 function이 된다.
그러나 User() 를 호출하는 부분에서 에러가 발생하는 이유는 클래스의 인스턴스를 생성하기 위해서는 new 키워드를 사용해야 한다.
new 키워드를 사용하여 클래스의 인스턴스를 생성하면 클래스의 생성자 함수가 호출되어 객체가 반환된다.
하지만 new 키워드 없이 클래스의 생성자 함수를 호출하면 에러가 발생한다.
따라서 아래와 같이 코드를 수정해야 한다.
const user = new User();
⨳⨳ 모르겠는 부분들
-클래스의 인스턴스란?
클래스의 인스턴스는 클래스를 기반으로 생성된 개별 객체를 말한다.
클래스는 객체를 생성하기 위한 템플릿이며 클래스의 인스턴스는 이 템플릿을 사용하여 생성된 구체적인 객체이다.
예를 들어 다음과 같이 User 클래스의 인스턴스를 생성할수 있다.
위의 코드에서 user는 User 클래스의 인스턴스이다.const user = new User();
new User()를 통해 User 클래스의 생성자 함수가 호출되고 그 결과로 새로운 객체가 생성되어 user 변수에 할당된다.
- class User{ constructor() {} }; 이게 왜 함수일까 ? function도 없는데
클래스는 내부적으로는 함수로 동작한다.
constructor 메서드는 클래스 내에서 객체를 초기화하기 위해 호출되는 특별한 메서드
클래스 정의는 함수 선언과 유사하다.
클래스를 정의하는 class 키워드를 사용하는 것은 함수를 정의하는 function 키워드를 사용하는 것과 유사하다.
클래스의 이름은 함수의 이름으로 사용되고 중괄호 내부에는 클래스의 메서드가 정의된다.
- 오해하지 말자
클래스 생성자 함수와 css의 클래스는 서로 다른 개념이다.
자바스크립트에서의 클래스 생성자 함수는 객체 지향 프로그래밍의 개념을 기반으로 한 객체 생성과 초기화를 위한 함수이다.
⨳⨳ 클래스 생성자 함수를 사용하는 이유
-1.객체 초기화 : 클래스 생성자 함수는 클래스의 인스턴스를 초기화하기 위한 로직을 포함할수 있다.
객체를 생성하고 초기 속성 값을 설정하는 등의 작업을 생성자 함수 내에서 수행 가능하다.
-2.인스턴스 고유 데이터 : 생성자 함수의 매개변수를 통해 인스턴스에 고유한 데이터를 전달 가능하다.
ex) 예시 코드
class User { constructor(name, age) { this.name = name; this.age = age; } sayHi() { console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old.`); } } const user1 = new User("John", 25); user1.sayHi(); // 출력: Hi, I'm John and I'm 25 years old. const user2 = new User("Jane", 30); user2.sayHi(); // 출력: Hi, I'm Jane and I'm 30 years old.// 위의 코드에서 User 클래스의 생성자 함수는 name 과 age라는 두 개의 매개변수를 받는다.
-3. 메서드 정의 : 생성자 함수 내에서 클래스의 메서드를 정의 가능하다.
이 매개변수를 통해 각 인스턴스에 고유한 데이터를 전달받는다.
user1 인스턴스는 "John"과 '25'를 인수로 전달하여 생성되었으며
user2 인스턴스는 "Jane"과 '30'을 인수로 전달하여 생성되었다.
각 인스턴스는 생성자 함수 내부의 this.name 과 this.age에 해당 값을 할당받아 고유한 속성 값을 가지게 된다.
이러한 메서드는 해당 클래스의 인스턴스에서 사용할수 있다. (동일한 클래스의 모든 인스턴스에서 공유된다.)
ex)예시 코드
class User { constructor(name) { this.name = name; } sayHi() { console.log(`Hi, I'm ${this.name}.`); } static greet() { console.log("Hello, everyone!"); } } const user1 = new User("John"); user1.sayHi(); // 출력: Hi, I'm John. const user2 = new User("Jane"); user2.sayHi(); // 출력: Hi, I'm Jane. User.greet(); // 출력: Hello, everyone!
위의 코드에서 User 클래스의 생성자 함수 내에는 sayHi() 메서드와 great() 정적 메서드가 정의되어 있다.
sayHi() 메서드는 각 인스턴스의 name 속성 값을 사용하여 메시지를 출력한다.
user1.sayHi()와 user2.sayHi()를 호출하면 각각 해당 인스턴스의 이름에 맞는 메시지가 출력된다.
great() 메서드는 static 키워드가 붙어있는 정적 메서드로 클래스 자체에서 호출 가능하다.
요약:
sayHi() 메서드는 인스턴스에서 호출되는 메서드이므로 각 인스턴스마다 다른 name 값을 가질수 있다.
반면에 great() 메서드는 클래스 자체에 속하는 정적 메서드이므로 인스턴스와는관련이 없이 클래스 자체에서 호출된다.
따라서 great() 메서드는 모든 인스턴스에서 공유되는 동일한 동작을 수행한다.
클래스 표현식
// 함수처럼 클래스도 다른 표현식 내부에서 정의,전달,반환,할당 가능하다.
// 먼저 클래스 표현식을 만들어 보자.
let User = class {
sayHi() {
alert("안녕하세요.");
}
};
// 기명 함수 표현식과 유사하게 클래스 표현식에도 이름을 붙일수가 있다.
// 클래스 표현식에 이름을 붙이면 이 이름은 오직 클래스 내부에서만 사용 가능하다.
// 기명 클래스 표현식(Named Class Expression)
// (명세서엔 없는 용어이지만, 기명 함수 표현식과 유사하게 동작합니다.)
let User = class MyClass {
sayHi() {
alert(MyClass); // MyClass라는 이름은 오직 클래스 안에서만 사용할 수 있습니다.
}
};
new User().sayHi(); // 원하는대로 MyClass의 정의를 보여줍니다.
alert(MyClass); // ReferenceError: MyClass is not defined, MyClass는 클래스 밖에서 사용할 수 없습니다.
// new User()를 통해 User 클래스의 인스턴스를 생성한다.
// 생성된 인스턴스에 대해 sayHi() 메서드를 호출한다.
// 여기에서 주목해야 할 점은 클래스 표현식에서 사용된 이름은 클래스의 내부에서만 유효하다.
클래스 필드
// 클래스 필드(class field)라는 문법을 사용하면 어떤 종류의 프로퍼티도 클래스에 추가할수 있다.
클래스 User에 name 프로퍼티를 추가해보자.
class User {
name = "보라";
sayHi() {
alert(`${this.name}님 안녕하세요!`);
}
}
new User().sayHi(); // 보라님 안녕하세요!
// 클래스를 정의할 때 <프로퍼티 이름>=<값>을 써주면 간단히 클래스 필드를 만들수 있다.
// 클래스 필드의 중요한 특징 중 하나는 User.prototype이 아닌 개별 객체에만 클래스 필드가 설정된다는 점
class User {
name = "보라";
}
let user = new User();
alert(user.name); // 보라
alert(User.prototype.name); // undefined
user.name은 클래스의 인스턴스 속성에 접근하고
user.prototype.name은 클래스의 프로토타입 객체에 접근(메서드가 있어야함)
'ko.javascript' 카테고리의 다른 글
| ko javascript (day-1 일차때 사용했던 클래스 상속에 대해서) (0) | 2023.06.23 |
|---|---|
| ko javascript(async 함수 project day-5와 연관) (0) | 2023.06.21 |
| ko javascript (0) | 2023.06.20 |
| ko javascript (0) | 2023.06.19 |