Класс недвижимости в JavaScript - PullRequest
4 голосов
/ 06 февраля 2020

У меня вопрос о свойствах класса. Я создам пример для лучшего понимания. Допустим, у нас есть класс.

   class Person {}

И мы хотим добавить свойство. Как мы это делаем? Из того, что я прочитал, есть 2 способа:

  class Person {myProperty ='Something'} //As shown at https://javascript.info/class. If we use console.log(Person) the property will not show

Теперь давайте создадим еще один класс, расширяющий Person, скажем, Athlete, и я хочу изменить myProperty:

  class Athlete extends Person{// If we use console.log(Athlete.myProperty ) it will show undefined
       myProperty='Something else'// it changes the property

        writeSomething() {
            console.log(this.myProperty);
        }
   }

Теперь давайте создадим новый объект, использующий Athlete в качестве конструктора

const athlete = new Athlete();
console.log(athlete)// It will have the property myProperty with value 'Something else'

Мои вопросы:

  1. Где хранится myProperty, я не могу найти его где-либо внутри Person или Athlete?
  2. Почему я могу получить доступ к myProperty внутри writeSomething ()?
  3. Почему myProperty появляется внутри спортсмена, когда он больше нигде не появлялся?
  4. Это другой способ записи свойств в отличие от Person .myProperty или это что-то еще?

Спасибо,

Elanvi

Ответы [ 4 ]

2 голосов
/ 06 февраля 2020

Прежде всего, они не являются "свойствами класса". Это свойства экземпляра, объявленные заранее. Это дает вам четкое представление о том, какие поля (свойства) можно ожидать от экземпляра класса .

На основе документации :

Publi c и объявления частных полей являются экспериментальной функцией (стадия 3) , предложенной на TC39, комитете по стандартам JavaScript. Поддержка в браузерах ограничена, но эту функцию можно использовать на этапе сборки с такими системами, как Babel.

Итак, основываясь на предложении в ссылке, ваш код предназначен для объявления publi c свойства экземпляров класса:

class Person {
  myProperty ='Something' // this means anyone can access the property
}

Для частных свойств они предлагают следующий синтаксис:

class Person {
  #myPrivateProperty ='Something' // this means only the instance methods have access
}

Чтобы ответить на ваши вопросы :

  1. Где хранится myProperty, я не могу найти его где-либо внутри Person или Athlete?

Он хранится как свойство экземпляра объекта. экземпляр класса Person. Поскольку Athlete расширяет его, экземпляру Athlete также будет присвоено то же свойство. Прочитайте Объектно-ориентированное программирование для получения более подробной информации.

Почему я могу получить доступ к myProperty внутри writeSomething ()?

writeSomething() - это метод экземпляра, поэтому он имеет доступ к любому свойству экземпляра. (publi c и private)

Почему myProperty появляется внутри спортсмена, когда он больше нигде не появляется?

Он также должен появляться в экземпляре Person. Например, вы можете написать:

const person = new Person();
person.myProperty = 'new Something';
Является ли это другим способом записи свойств в отличие от Person.myProperty или это что-то еще?

Это просто объявление свойств экземпляра, которое стало более простым и интуитивно понятным и подразумеваемым модификатор доступа (то есть public).


Наконец, если вы хотите объявить свойство класса , вам нужно указать его как static свойство, например:

class Person {
  static myProperty = 'some value';
}
console.log(Person.myProperty);
1 голос
/ 06 февраля 2020

Я постараюсь ответить на ваши вопросы как можно лучше:

  1. Где хранится myProperty, я не могу найти его где-либо внутри Person или Athlete?

Запись:

class Person { myProperty = 'Something' }

Это то же самое, что и запись:

class Person {
  constructor() {
    this.myProperty = 'Something';
  }
}

Насколько я понимаю, написание первого способа фактически добавляет определение свойства в конструктор - вы не увидите myProperty в прототипе Person, свойство нигде не будет существовать, пока не будет создан экземпляр с new Person и не будет вызван конструктор.

Почему я могу получить доступ к myProperty внутри writeSomething ()?

Вы можете получить доступ к myProperty внутри writeSomething через контекст this, так как он будет ссылаться на экземпляр Person, если не указано иное.

Почему myProperty появляется внутри спортсмена, когда он больше нигде не появляется?

Свойство не находится внутри Athlete per se, но без определения собственного конструктора он унаследует конструктор родительского класса, что означает, что * экземпляры Athlete получат то же свойство, которое определено при их создании. Если бы вы добавили конструктор к Athlete, вам пришлось бы вызвать конструктор super (т.е. конструктор Person), и в это время свойство будет определено в экземпляре.

Это другой способ записи свойств в отличие от Person.myProperty или что-то еще?

Как описано выше, вы также можете определить эти свойства экземпляра в конструкторе с помощью this.myProp = 'my value'. Вы можете прочитать здесь о том, как использовать поля класса.

0 голосов
/ 06 февраля 2020

Где хранится myProperty, я не могу найти его где-нибудь внутри Person или Athlete?

Publi c поля экземпляра для классов являются syntacti c сахар для создания экземпляра собственных свойств внутри конструктора класса.

class Person { constructor() { this.p1 = 'p1 value' } }

С учетом следующего:

class Person { p1 = 'p1 value'; p2 = 'p2 value' }

class Athlete extends Person { p1 = 'p1 overridden value' }

Свойство prototype Person класс помещается в цепочку прототипов свойства prototype класса Athlete.

console.log(Athlete.prototype.__proto__ === Person.prototype) // true

Свойство prototype класса Person не содержит свойства p1 потому что он будет динамически добавляться конструктором по умолчанию класса Person при создании экземпляра.

console.log(Person.prototype.hasOwnProperty('p1')) // false

const p = new Person()

При обновлении Person конструктор динамически добавляет свойство к результирующему instance.

console.log(p.hasOwnProperty('p1')) // true

const a = new Athlete()

При обновлении суперконструктора Athlete Person неявно вызывается против экземпляра Athlete, помещая в экземпляр как p1, так и p2, наконец, Athlete конструктор запущен и p1 перезаписывается.

console.log(a.hasOwnProperty('p1')) // true
console.log(a.hasOwnProperty('p2')) // true
console.log(a.p1) // p1 value overridden

Почему я могу получить доступ к myProperty внутри writeSomething ()?

Это обычное this поведение. При вызове функции в качестве метода целью метода является объект, к которому она была вызвана. В этом случае экземпляр Athlete.

0 голосов
/ 06 февраля 2020

1) Где хранится myProperty, я не могу найти его где-либо внутри Person или Athlete?

Переменные, к которым можно получить доступ внутри Person или Athlete, называются static переменные класса. Вы можете определить их, выполнив:

Person.staticProperty = 'Something';

или

class Person {
  static staticProperty = 'Something';
}

Эта переменная может быть доступна внутри вашего класса:

class Person {
   static staticProperty = 'Something';

  logStaticProperty() {
    console.log(Person.staticProperty);
  }
}

2) Почему я могу получить доступ к myProperty внутри writeSomething ()?

Когда вы создаете экземпляр класса с помощью new, вы можете прикрепить переменные, которые изолированы к этому единственному экземпляру. Синтаксис, используемый в конструкторе, присоединяет переменную к экземпляру.

3) Почему myProperty появляется внутри спортсмена, когда он больше нигде не появляется?

См. # 2.

4) Это другой способ записи свойств в отличие от Person.myProperty или что-то еще?

Использование метода constructor функционально эквивалентный

class Person {
  constructor() {
    this.myProperty = 'Somethin';
  }
}
...