Доступ к свойству класса JavaScript в родительском классе - PullRequest
0 голосов
/ 02 апреля 2019

Есть ли способ, которым это возможно в ES6 - или есть хорошее решение, если это не так (как представляется вероятным):

class Parent {
    constructor() {
        console.log(this.name);
    }
}

class Child extends Parent {
     name = "Child Name";
}

const c = new Child();
// Should console.log "Child Name";

(Исходя из Python, где он полностью работает!)

Ответы [ 3 ]

1 голос
/ 02 апреля 2019

Чтобы сохранить значение свойства name родительского объекта, вы можете просто оставить конструктор вне своего дочернего класса.В качестве альтернативы, если вы хотите обновить определенное свойство (в данном случае name), вам нужно установить this.name в конструкторе ПОСЛЕ вызов super() - явный вызов super()требуется, прежде чем вы сможете установить this свойства, в противном случае JavaScript выдаст ошибку.

Вот пример того, что я пытаюсь объяснить выше:

class Parent {
  constructor() {
    this.name = "Parent Name";
  }
}

class ChildWithConstructor extends Parent {
  constructor() {
    super();
    this.name = "Child Name";
  }

  sayName() {
    console.log(`The constructor call updated the property value set in the parent contructor: ${this.name}`)
  }
}

class ChildWithoutConstructor extends Parent {
  sayName() {
    console.log(`No constructor call retains the property values set in the parent contructor: ${this.name}`)
  }
}

const c = new ChildWithConstructor();
const nc = new ChildWithoutConstructor();
c.sayName();
nc.sayName();
1 голос
/ 02 апреля 2019

Конструктор родителя вызывается до того, как дочерний элемент может инициализировать данные своего экземпляра, поэтому вы не можете ссылаться на экземпляр дочернего элемента в конструкторе родительского элемента.Это просто неправильный дизайн ООП (по крайней мере, в Javascript).Если родительский объект хочет получить доступ к свойству в конструкторе, тогда определите и инициализируйте свойство в конструкторе родительского объекта (дочерний элемент все еще может использовать его).

Родители не должны зависеть от детей - дети зависят от родителей.

Итак, это ошибочная конструкция ООП.Вы не показываете реальную проблему, которую пытаетесь решить, поэтому мы не можем точно предложить, какой будет правильный дизайн для данной проблемы.


Чтобы рассмотреть, порядок вещей:

  1. Дочерний конструктор называется
  2. Дочерний конструктор вызывает super(...) для выполнения родительского конструктора
  3. Родительский конструктор инициализирует данные своего экземпляра
  4. После родительского конструкторавозвращает, конструктор Child имеет возможность инициализировать свои данные экземпляра

Если вы используете определения классов 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";
0 голосов
/ 02 апреля 2019

Из родительского класса доступ к полям дочернего класса не может быть получен. От ребенка к родителю - вы можете использовать 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();
...