eyabc / blog-comment

1 stars 0 forks source link

https://eyabc.github.io/Doc/dev/core-javascript/%ED%81%B4%EB%9E%98%EC%8A%A4.html #13

Open utterances-bot opened 4 years ago

utterances-bot commented 4 years ago

ES6 클래스 | 삽질하는 개발자

https://eyabc.github.io/Doc/dev/core-javascript/%ED%81%B4%EB%9E%98%EC%8A%A4.html

pul8219 commented 4 years ago

클래스의 전반적인 내용, 클래스도 호이스팅이 된다는 점, 그리고 상속, super 등의 내용을 잘 이해할 수 있었습니다. 양이 정말 방대하네요👍 이렇게 높은 질의 문서를 위해서 저도 미리미리 하고 시간투자를 더 해야겠습니다

khw970421 commented 4 years ago

잘읽었습니다. 하나 질문이 있는데요

서브 클래스 static 메서드에서 super.속성명 수퍼 클래스의 static 속성 접근 서브 클래스 인스턴스 메서드에서 super.속성명 수퍼 클래스의 인스턴스 속성에 접근

이부분인 클래스 상속의 super부분 내용에서 둘다 super.속성으로 접근을 한다 했는데

class Person {
    static staticMethod() {
        return "I'm a static method.";
    }
    instanceMethod() {
        return "I'm a instance method.";
    }
}
class Student extends Person {
    f(){
        return super.instanceMethod()+" instance작동";
    }
    f1(){
        return Person.staticMethod()+" static작동";
    }
}
const p = new Student();
console.log(p.f());
console.log(p.f1());

이렇게 instance 메소드를 이용할때는 super를 써야하고 static 메소드를 이용할때는 Person을 써야 정상적 결과가 나오던데 Person.staticMethod() => super.staticMethod()이러면 에러가 나서여 제가 생각하는 부분이 맞는건지 댓글남깁니다.

eyabc commented 4 years ago

코드로 다음과 같이 표현할 수 있습니다.

class Person {
    this.publicVar = 'public';
    static staticVar = 'static var';  // 수퍼 클래스의 static 속성
    // 수퍼 클래스의 인스턴스 속성

    static staticMethod() { // 본문과  관계없는 구문 
        return "I'm a static method.";
    }
    instanceMethod() {  // 본문과  관계없는 구문 
        return "I'm a instance method.";
    }
}

class Student extends Person {

    method(){
        return this.publicVar+" instance작동";
    }
    static staticMethod(){
        return super.staticVar+" static작동";
    }
}

publicVar = 'student public';

let student = new Student();
console.log(student.method());
console.log(Student.staticMethod());

인스턴스 메서드는 this.~ 로 수퍼 클래스의 인스턴스에 접근할 수 있는데요, 정확히 말하자면 상속받은 Student 클래스는 constructor 가 없다면 자동으로 생성 되고 그 안에서 super() 를 호출하여 수퍼클래스 생성자를 호출하게 됩니다. 그러면서 Student 클래스 에서 People 클래스의 생성자를 호출 하였기 때문에 this.publicVar = 'public'; 는 student 객체의 프로퍼티가 되므로 this.publicVar 사용할 수 있게 됩니다.

class Student extends Person {
    constructor(...args) {
       super(...args);
    }
    method(){
        return this.publicVar+" instance작동";
    }
    static staticMethod(){
        return super.staticVar+" static작동";
    }
}

클래스나 객체의 메서드에는 [[HomeObject]] 라는 특수 프로퍼티를 갖고 있는데요, 여기의 값에는 현재 객체가 저장됩니다. 위의 예시에서 Student 클래스의 method() 메서드의 [[HomeObject]] 는 Student 가 되고, Person 클래스의 instanceMethod() 메서드의 [[HomeObject]] 는 Person 이 됩니다. 이 때, super 는 [[HomeObject]] 의 값을 참조하여 프로토타입 으로부터 수퍼클래스의 메서드 를 가져올수 있게 된다고 합니다.

image

그림과 같이 static 은 People 의 생성자 함수의 프로퍼티 로 저장이 되고 일반 속성을 제외한 일반 메서드는 People 생성자함수의 prototype 에 저장이 됩니다. (People.prototype)

그리고 Student 의 static 메서드에서 super 를 쓰면 생성자함수의 프로토타입 체인을 타고 People 생성자 함수의 프로퍼티에 있는 static 변수나 메서드를 탐색할 수 있게 된다 라고 이해하면 될것 같습니다.

JunilHwang commented 4 years ago

image

이 부분은 잘못되었습니다.

image

JunilHwang commented 4 years ago

image

정적 메서드에서도 this를 사용할 수 있습니다.

class Foo {}
Foo.a = 10;
Foo.b = 20;
Foo.c = function () {
  return this.a + this.b;
}
console.log(Foo.c()); // 30

image

JunilHwang commented 4 years ago

image

참고로 private 필드와 메소드는 상속되지 않습니다 원래 하위 클래스에서 상위 클래스의 필드와 메소드에 접근하기 위해선 protected 라는 접근제한자를 사용합니다. 그런데 JS에는 private만 있고 protected가 없기 때문에 private으로 선언된 것은 아예 상속되지 않습니다.

JunilHwang commented 4 years ago

image

참고로 super는 항상 생성자 최상단에서 사용되어야합니다. super보다 위에 있는 구문이 있을 경우 에러가 발생합니다.

JunilHwang commented 4 years ago

ES5와 ES6가 정확히 어떻게 다른지 설명하는 글입니다.

https://www.bsidesoft.com/5370

핵심은 바로 "상속" 입니다.

ES5로 ES6에서 사용하는 상속을 완벽하게 흉내 내는 것은 불가능합니다.

JunilHwang commented 4 years ago

전체적으로 꼼꼼하게 작성된 게시물이내요! 굉장히 공을 많이 들여 작성한 것이 티납니다 ㅎㅎ