diff --git "a/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/example.js" "b/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/example.js" new file mode 100644 index 0000000..8c28d9f --- /dev/null +++ "b/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/example.js" @@ -0,0 +1,28 @@ +// super 키워드 활용 + +class Base { + constructor(a, b) { + this.a = a; + this.b = b; + } + + saySum () { + return this.a + this.b ; + } +} + +class Derived extends Base { + constructor(a, b, c) { + // super의 호출, 수퍼클래스의 constructor를 호출한다. + super(a, b); + this.c = c + } + + saySum () { + // super의 참조, 수퍼클래스의 메서드를 호출한다. + return super.saySum() + this.c; + } +} + +const derived = new Derived(1, 2, 3); +console.log(derived.saySum()); // 6 \ No newline at end of file diff --git "a/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/\352\270\260\354\226\265\354\227\220 \353\202\250\353\212\224 \353\202\264\354\232\251.md" "b/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/\352\270\260\354\226\265\354\227\220 \353\202\250\353\212\224 \353\202\264\354\232\251.md" new file mode 100644 index 0000000..fdc5563 --- /dev/null +++ "b/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/\352\270\260\354\226\265\354\227\220 \353\202\250\353\212\224 \353\202\264\354\232\251.md" @@ -0,0 +1,79 @@ +# ✏️ 기억에 남는 내용 + +## **클래스란?** +--- +### **프로토타입의 문법적 설탕?** +클래스는 일종의 함수이며 기존 프로토타입 기반 패턴을 클래스 기반 패턴처럼 사용할 수 있도록 하는 `문법적 설탕`이라고 볼 수도 있지만, 생성자 함수와 정확히 동일하게 동작하지는 않는다. +- 클래스를 프로토타입 기반 객체 생성 패턴의 단순한 문법적 설탕이라고 보기보다는 '새로운 객체 생성 메커니즘'으로 보는 것이 좀 더 합당하다. (인스턴스를 생성하는 것이 유일한 존재 이유) + +## **클래스 정의** +--- +`class` 키워드를 사용하여 정의(일반적)하거나 표현식으로 정의할 수 있다. 따라서 클래스는 값으로 사용할 수 있는 일급 객체이다. +- 클래스의 몸체에는 0개 이상의 '메서드만' 정의할 수 있다. + +### **클래스 호이스팅** +클래스 선언문도 변수 선언, 함수 정의와 마찬가지로 호이스팅이 발생하지만 let, const 키워드로 선언한 변수처럼 호이스팅된다. (호이스팅이 발생하지 않는 것처럼 동작) + +## **클래스의 메서드** +--- +클래스 몸체에서 정의할 수 있는 메서드는 constructor(생성자), 프로토타입 메서드, 정적 메서드가 있다. +### **constructor** +인스턴스를 생성하고 초기화하기 위한 특수한 메서드다.(이름 변경 금지) +### **프로토타입 메서드** +생성자 함수에 의한 객체 생성 방식과는 달리 명시적으로 프로포타입에 메서드를 추가하지 않아도 기본적으로 프로토타입 메서드가 된다. +### **정적 메서드** +인스턴스를 생성하지 않아도 호출할 수 있는 메서드로, 메서드에 `static` 키워드를 붙이면 된다. + +### **정적 메서드 vs 프로토타입 메서드** +1. 속해 있는 프로토타입 체인이 다르다. +2. 그러므로 정적 메서도는 클래스로 호출하고, 프로토타입 메서드는 인스턴스로 호출한다. +3. 정적 메서드는 인스턴스 프로퍼티를 참조할 수 없지만 프로토타입 메서드는 인스턴스 프로퍼티를 참조할 수 있다. + +```JS +class Person { + constructor(name) { + this.name = name; + } + + sayHi() { + console.log('Hi! My name is ${this.name}'); + } + + static sayHello() { + console.log('Hello'); + } +} + +const me = new Person('Lee'); + +console.log(me.name); +// 프로토타입 메서드 호출 +me.sayHi(); +// 정적 메서드 호출 +Person.sayHello(); +``` + +## **프로퍼티** +--- +### **인스턴스 프로퍼티** +constructor 내부에서 정의하여 클래스가 생성한 인스턴스의 프로퍼티가 된다. +### **접근자 프로퍼티** +접근자 함수(데이터 프로퍼티의 값을 읽거나 저장할 때 사용, getter 함수와 setter 함수)로 구성된 프로퍼티로, +### **클래스 필드 정의 제안** +'클래스 필드'란 클래스 기반 객체지향 언어에서 클래스가 생성할 인스턴스의 프로퍼티를 가리키는 용어다. +- '자바스크립트'의 클래스에서는 인스턴스 프로퍼티의 선언과 초기화는 반드시 constructor 내부에서, this에 프로퍼티를 추가해야한다. +- 하지만 '자바'의 클래스에서는 클래스 필드를 마치 변수처럼 클래스 몸체에 this 없이 선언하고, 클래스 필드를 참조할 때에도 this 없이 참조할 수 있다. +- 캡슐화를 완전하게 지원하지 않고 접근 제한자를 지원하지 않는 자바스크립트의 단점을 보완하고자 `private 필드 정의` 제안, 정적 필드를 정의하기 위해 `static 필드 정의` 제안 + +## 상속에 의한 클래스 확장 +--- +상속에 의한 클래스 확장은 기존 클래스를 상속 받아 새로운 클래스를 확장하여 정의하는 것이다. +- 기존 클래스의 속성을 그대로 사용하고 자신만의 고유한 속성을 추가하여 확장한다. 코드 재사용 관점에서 매우 유용하다. + +### **`extends` 키워드** +상속을 통해 클래스를 확장할 때 사용하는 키워드이다. ***수퍼클래스*** (상속된 클래스, 베이스 클래스, 부모 클래스)와 ***서브클래스*** (상속을 통해 확장된 클래스, 파생 클래스, 자식 클래스) 간의 상속 관계를 설정한다. +- `extends` 키워드 다음에는 클래스뿐만이 아니라 함수 객체로 평가될 수 있는 모든 표현식을 사용할 수 있다. 이를 통해 동적으로 상속받을 대상을 결정할 수 있다. (`extends` 키워드) +- 따라서 String, Number, Array 같은 표준 빌트인 객체도 `extends` 키워드를 사용하여 확장할 수 있다. + +### **`super` 키워드** +super은 함수처럼 호출할 수도, 식별자처럼 참조할 수도 있는 키워드이다. 호출할 경우 '수퍼클래스의 constructor'을 호출하고, 참조할 경우 '수퍼클래스의 메서드'를 호출한다. (활용은 예제코드 참고) diff --git "a/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/\355\200\264\354\246\210.md" "b/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/\355\200\264\354\246\210.md" new file mode 100644 index 0000000..1efc982 --- /dev/null +++ "b/9\354\243\274\354\260\250 (25\354\236\245)/25. \355\201\264\353\236\230\354\212\244/LSH0125/\355\200\264\354\246\210.md" @@ -0,0 +1,18 @@ +# 📝 간단한 퀴즈 + +1. 클래스 몸체에서 정의할 수 있는 메서드 3종류를 쓰고 간단히 정리해보자. +2. 클래스를 확장할 때의 '상속'과 프로토타입 기반의 '상속'의 차이는 무엇인지 간단히 정리해보자. +3. 다음 코드에서 서브 클래스와 수퍼 클래스 두 쌍을 찾아보자. +```JS +class Base {} +class Derived extends Base {} + +class MyArray extends Array { + uniq() { + return this.filter((v, i, self) => self.indexOf(v) === i); + } + average() { + return this.reduce((pre, cur) => pre + cur, 0) / this.length; + } +} +``` \ No newline at end of file