클래스

2022. 6. 19. 22:36·JavaScript
728x90
반응형

클래스는 프로토타입의 문법적 설탕인가?

* 문법적 설탕 : Syntax Sugar

https://en.wikipedia.org/wiki/Syntactic_sugar

 

Syntactic sugar - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Programming language syntax designed for ease of use In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to e

en.wikipedia.org

- 프로그래밍 언어에 적용되는 개념이다

- 사람이 이해하기 쉽고 표현하기 쉽게 컴퓨터 언어를 디자인해 놓은 문맥

- 깔끔하고 명확하게 표현가능

- 기능과 표현은 똑같이 유지됨

 

클래스 

  • 클래스를 표현식으로 정의할 수 있다는 것 -> 클래스가 일급객체다
  • 클래스는 함수로 평가된다
  • 클래스는 호이스팅이 발생한다(var,let,const,function,function*,class 키워드를 사용한 모든 식별자는 호이스팅됨)
    -> 모든 선언문은 런타임 이전에 먼저 실행
  • 클래스 몸체에서 정의할 수 있는 메서드는 constructor,프로토타입 메서드,정적 메서드 3가지다
  • constructor는 클래스내에 최대 1개만 존재할 수 있다
  • 자동으로 프로토타입 체인이 걸림
  • static 정적 메서드는 생성자,클래스 그 자체에서 호출가능한 메서드
  •  
class Person {}

const Person = class {};

cosnt Person=class MyClass {};

class Person{
  constructor(name){
    this.name=name;
    // this.name='na' 이런식으로 고정값 초기화도 가능하다
    // 암묵적으로 this ( 인스턴스 )를 반환하는데 
    // return {} 명시적으로 객체를 반환하면 this 반환이 무시된다 (원시값은 this가 이김)
    // 여기에는 return문 쓰지마라
  }
  sayHi(){
    console.log(`안녕하세요 ${this.name}`);
  }
  static sayHello(){
    console.log('Hello');
  }
}

const me =new Person('NA');


me.sayHi()
Person.sayHello()

클래스의 인스턴스 생성과정

  1. 인스턴스 생성과 this 바인딩
    new 연산자와 함께 클래스를 호출하면 constructor 내부 코드가 실행되기 전에 암묵적으로 빈 객체가 생성되고,
    이 객체가 클래스가 생성한 인스턴스다. 이 인스턴스의 프로토타입으로 클래스의 prototype 프로퍼티가 가리키는
    객체가 설정되고, 인스턴스는 this에 바인딩 된다. -> constructor 내부의 this는 클래스가 생성한 인스턴스를 가리킨다
  2. 인스턴스 초기화
    constructor의 내부 코드가 실행되어 this에 바인딩되어 있는 인스턴스를 초기화 한다.
  3. 인스턴스 반환(this 반환)
class Person{
  constructor(name){
    1. 암묵적으로 인스턴스가 생성되고 this에 바인딩된다.
    console.log(this);
    console.log(Object.getPrototypeOf(this)===Person.prototype);

    2. this에 바인딩되어 있는 인스턴스를 초기화 한다
    this.name=name
    3. this 암묵적 반환
  }
}

프로퍼티

  • 인스턴스 프로퍼티 (항상 public)
  • 접근자 프로퍼티
class Person{
  constructor(fName,lName){
    this.fName=fName
    this.lName=lName
  }

  get fullName(){
    return `${this.fName} ${this.lName}`
  }
  set fullName(name){
    [this.fName,this.lName]=name.split(' ')
  }
}

const me =new Person('Hi','There')
 
console.log(me.fullName); //Hi There

me.fullName='Bye de'

console.log(me.fullName); //Bye de

getter,setter함수 -> get, set 키워드를 사용해서 정의 *setter는 단 하나의 값만 할당받기 때문에 매개변수는 딱 하나여야함

 

클래스 필드 정의 제안

자바의 클래스 필드는 클래스 내부에서 변수처럼 사용된다

public class Person{
//클래스 필드 정의
  private String firstName ="";
  private String lastName="";
//생성자
  Person(String firstName,String lastName){
    this.firstName=firstName
    this.lastName=lastName
    }
  public String getFullName(){
 //클래스 필드 참조
    return firstName + " " + lastName
    }
}

자바스크립트의 클래스

  • 인스턴스를 생성할 때 클래스 필드를 초기화해야할 필요가 있다면 constructor에서 포기화 해야한다.
class Person{
 name; //초기화 안하면 undefined
 constructor(name){
  this.name=name
  }
}
  • 함수를 클래스 필드에 추가 -> 함수는 인스턴스 메서드됨 -> 클래스 필드에 함수를 할당하는 것은 권장 X

Private 필드

constructor 내부에 정의해선 직접 정의 X (에러 발생)

class Person{
  #name='' //private

  constructor(name){
    this.#name=name
  }
}

const me=new Person('Lee');
console.log(me.#name);
//SyntaxError: Private field '#name' must be declared in an enclosing class

#으로 private 필드를 정의 -> 외부에서 사용 안됨

class Person{
  #name='' //private

  constructor(name){
    this.#name=name
  }

  get name(){
    return this.#name.trim()
  }
}

const me=new Person('Lee');
console.log(me.name);

접근자 프로퍼티를 사용하면 접근이 가능함

 

상속

class Animal{
  constructor(age,weight){
    this.age=age;
    this.weight=weight
  }

  eat() {return 'eat'}

  move() {return 'move'}
}

class Bird extends Animal{
  fly() {return 'fly'}

}

const bird =new Bird(1,5);

console.log(bird);
console.log(bird.eat());

bird라는 클래스가 Animal(부모)에 있는 eat을 상속받아 사용할 수 있다

서브클래스에는 암묵적으로 constructor가 정의된다

*동적상속 -> boolean 값으로 동적으로 할당결정

 

Super

class Base{
  constructor(a,b){
    this.a=a;
    this.b=b;
  }
}

class Base2 extends Base{
  constructor(a,b,c){
    super(a,b)
    this.c=c
  }
}

const b=new Base2(1,2,3)
console.log(b); //Base2 { a: 1, b: 2, c: 3 }

※super 사용시 주의사항

1. 서브클래스에 constructor 사용시 super를 반드시 (맨 위에)호출해야한다

이유)

자바스크립트 엔진은 부모/자식클래스 구분을 위해서 내부슬롯 [[ConstructorKind]]를 갖고, 상속여부에 따라서 각각 내부슬롯에 값이 설정된다.

이후 new 연산자와 함께 호출되었을  때 암묵적으로 빈 객체, 즉 인스턴스를 생성하고 이를 this에 바이딩한다.

이때 서브클래스는 자신이 직접 인스턴스를 생성하지 않고 부모 클래스로 위임한다  때문에 super을 반드시 호출해야한다

 

맨위에 호출해야하는 이유) 

서브클래스는 super가 반환한 인스턴스를 this에 바인딩하여 그대로 사용하기에 super()가 위에 있어야지 this도 사용가능

class Base{
  constructor(name,age){
    console.log(this); //Base2 {}
    console.log(new.target); //[class Base2 extends Base]
    
    this.name=name
    this.age=age
  }
  sayHi(){
    return `Hi ${this.name}`
  }
}

class Base2 extends Base{
  constructor(name,age,birth){
    super(name,age)
    this.birth=birth
  }
  sayHi(){
    return `${this.name} ${this.age} ${this.birth} ${super.sayHi()}`
  }
}

const b=new Base2('Tim','10','2129')

console.log(b.sayHi());

2. 서브클래스가 아닌곳에 super사용시 에러발생

 

*super 참조

메서드 내에서 super를 참조하면 수퍼클래스의 메서드를 호출할 수 있다.

class Base{
  constructor(name){
    this.name=name
  }
  sayHi(){
    return `Hi ${this.name}`
  }
}

class Base2 extends Base{
  sayHi(){
    return `${super.sayHi()}`
  }
}

const b=new Base2('Tim')

console.log(b.sayHi());

super 자신이 참조하고 있는 메서드가 바인딩되어 있는 객체의 프로토타입을 가리킨다

(sayHi() -> Base2.prototype -> Base.prototype) ==> super.sayHi()는 Base.prototype.sayHi()를 가리킨다

[[HomeObject]] => super참조가 잘 작동하게 하기위한 내부 슬롯

[[HomeObject]]를 가지고 있어야만 super 참조가 가능하고 ES6의 메서드 축약 표현으로 정의된 함수여야함

*ES6 메서드 축약 표현 < foo() {} >

 

728x90
반응형
저작자표시 (새창열림)

'JavaScript' 카테고리의 다른 글

배열  (0) 2022.06.28
ES6 함수의 추가 기능  (0) 2022.06.22
클로저(Closure)  (0) 2022.06.13
this / 실행 컨텍스트  (0) 2022.06.09
strict mode / 빌트인 객체  (0) 2022.05.24
'JavaScript' 카테고리의 다른 글
  • 배열
  • ES6 함수의 추가 기능
  • 클로저(Closure)
  • this / 실행 컨텍스트
Hun-bot
Hun-bot
IT를 중심으로 다양한 것
  • Hun-bot
    로봇이 만드는 눈사람
    Hun-bot
  • 전체
    오늘
    어제
    • All Article (128)
      • Programmers (6)
        • TIP (1)
        • SQL (2)
        • LV1 (1)
        • LV2 (2)
        • LV3 (0)
      • Baekjoon (31)
        • Bronze (10)
        • Silver (19)
        • Gold (2)
        • Platinum (0)
        • Diamond (0)
      • Leetcode (0)
        • Easy (0)
        • Medium (0)
        • Hard (0)
        • SQL (0)
      • 알고리즘(Algorithm) (42)
      • JavaScript (40)
      • Linux (7)
      • JSP (1)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      프로그래머스
      자바스크립트 #연습문제
      알고리즘 #Algorithm
      JS #JavaScript #프로그래머스 #카카오
      JavaScript #Set #Collection
      오블완
      티스토리챌린지
      Programmers
      Python #알고리즘
      JS #프로그래머스 #숫자의표현 #알고리즘
      LeetCode #JS #Javascript #Algorithm
      알고리즘
      고득점 Kit
      async await #js #문법 #자바스크립트 #비동기
      JS #클래스
      JS #javascript #객체 #Object
      리눅스 #입문
      JS #정규표현식
      리눅스
      JSP #Vscode #톰켓 #Tomcat #Java #Web #jdk
      SQL
      c++
      Vue #Vue.js #정리
      BaekJoon
      Algorithm
      JS #JavaScript #프로그래머스 #알고리즘
      Javascript
      백준
      자바스크립트
      프로그래머스 #자바스크립트 #JS
    • 최근 댓글

    • hELLO· Designed By정상우.v4.10.3
    Hun-bot
    클래스
    상단으로

    티스토리툴바

    티스토리툴바