访问父类中的JavaScript类属性

访问父类中的JavaScript类属性,javascript,es6-class,Javascript,Es6 Class,在ES6中有没有任何方法可以做到这一点?或者如果没有,有没有一个好的解决方案(看起来很可能): (来自Python,它完全可以工作!)在子级可以初始化其实例数据之前,会调用父级构造函数,因此您不能在父级构造函数中引用子级实例。这是错误的OOP设计(至少在Javascript中是如此)。如果父级希望访问构造函数中的属性,则在父级的构造函数中定义并初始化该属性(子级仍然可以使用它) 父母不应该依赖孩子——孩子依赖父母 所以,这是有缺陷的面向对象设计。您没有显示您试图解决的实际问题,因此我们无法真正建

在ES6中有没有任何方法可以做到这一点?或者如果没有,有没有一个好的解决方案(看起来很可能):


(来自Python,它完全可以工作!)

在子级可以初始化其实例数据之前,会调用父级构造函数,因此您不能在父级构造函数中引用子级实例。这是错误的OOP设计(至少在Javascript中是如此)。如果父级希望访问构造函数中的属性,则在父级的构造函数中定义并初始化该属性(子级仍然可以使用它)

父母不应该依赖孩子——孩子依赖父母

所以,这是有缺陷的面向对象设计。您没有显示您试图解决的实际问题,因此我们无法真正建议针对实际问题的正确设计


回顾一下,事情的顺序是:

  • 调用子构造函数
  • 子构造函数调用
    super(…)
    来执行父构造函数
  • 父构造函数初始化其实例数据
  • 父构造函数返回后,子构造函数有机会初始化其实例数据
  • 如果使用ES6类定义,则无法将此顺序更改为其他内容


    根据您对这个答案的最新评论,我认为没有比向每个孩子添加额外代码行更好的方法了:

    class Parent {
        constructor(name) {
            if (!name) {
                // could also throw an exception here if not
                // providing a name is a programming error and is not allowed
                this.name = "Default Name";
            } else {
                this.name = name;
            }
            console.log(this.name);
        }
    }
    
    class ChildA extends Parent {
         constructor() {
             super("ChildA Name");
         }
    }
    
    class ChildB extends Parent {
         constructor() {
             super("ChildB Name");
         }
    }
    
    const c = new ChildA();
    // Should console.log "ChildA Name";
    

    要保留父类的
    name
    属性的值,只需将构造函数从子类中删除即可。或者,如果要更新特定属性(
    name
    ,在本例中),则需要在调用
    super()
    之后,在构造函数中设置
    this.name
    ——在设置
    this
    属性之前,需要显式调用
    super()
    ,否则JavaScript将抛出一个错误

    下面是我试图在上面解释的一个例子:

    类父类{
    构造函数(){
    this.name=“父名称”;
    }
    }
    类ChildWithConstructor扩展了父类{
    构造函数(){
    超级();
    this.name=“子名称”;
    }
    sayName(){
    log(`构造函数调用更新了父构造函数中设置的属性值:${this.name}`)
    }
    }
    类ChildWithoutConstructor扩展了父类{
    sayName(){
    log(`没有构造函数调用保留父构造函数中设置的属性值:${this.name}`)
    }
    }
    const c=新的ChildWithConstructor();
    const nc=没有构造函数的新子级();
    c、 sayName();
    nc.sayName()从父类中,无法访问子类的字段。从子级到父级-您可以使用super

        class Parent {    
            constructor() {
              this.name="Parent Name";      
            };
        }
    
        class Child extends Parent {
          constructor(){
            super(name);
            console.log(this.name);
            this.name = "Child Name";
            console.log(this.name);    
          }
        }
    
        const c = new Child();
    

    唯一的方法是在子构造函数上调用名为init的方法,在父类上定义并使用init方法作为父构造函数

    这样,当子属性就绪时,将调用init

    类父类{
    构造函数(){
    }
    init(){
    console.log(this.name);
    }
    }
    类子级扩展父级{
    name=“子名称”;
    构造函数(){
    超级();
    //调用父初始化
    this.init();
    }
    }
    
    const c=新的子对象()我理解这个使用super()调用父方法的示例。问题在于父构造函数对
    this.name
    的引用是否指向在子构造函数中定义的
    name
    ——在调用
    Parent.constructor
    时。(这似乎不起作用)这里有一些误解。1.“首先,
    name=“Child name”
    不引用对象的属性。”OP使用的是类字段语法,目前是一个。2.“其次,您的孩子需要使用
    super()
    调用父级构造函数。第三,您的孩子定义ES6语法不正确。您需要定义子构造函数。”定义
    构造函数不需要派生类。如果未定义,则会隐式调用超类“
    构造函数”
    。“第四,在子级可以初始化其实例数据之前调用父级构造函数,因此您不能在父级构造函数中引用子级实例。”至少这一部分是正确的。这似乎是我想要的答案。简言之,不,不可能。我试图在Parent中创建一个数据对象,该对象(除其他外)包含初始化它的子对象的
    name
    字段。我想知道是否有一种方法可以做到这一点,而不必在每个子类(有很多)上定义构造函数,只需从子类中获取class属性。(因此,每个子类更改的位只是一行,而不是四行构造函数,我不需要它们,只需要定义一个变量。)但是,是的,不可能,因为父类是先初始化的。@user2672537-我添加了一个代码示例。在我看来,使用ES6类实现这一点的最干净的方法就是添加额外的代码行来定义子构造函数。@JordanRunning-仅供参考,我根据您的反馈整理了我的答案,并根据OP的评论添加了一些额外的信息。看起来我想做的事情实际上是不可能的。对于更多上下文,父构造函数将开始构造某种类型的数据对象,其中一个值是
    Child.name
    变量(以便数据对象跟踪实际实例化了许多子类中的哪一个)。但是,正如jfriend00的回答所说,“在孩子可以初始化他们的实例数据之前,会调用父母的构造函数”(这表明我想做的是不可能的)。
        class Parent {    
            constructor() {
              this.name="Parent Name";      
            };
        }
    
        class Child extends Parent {
          constructor(){
            super(name);
            console.log(this.name);
            this.name = "Child Name";
            console.log(this.name);    
          }
        }
    
        const c = new Child();