I have a question about class properties. I'll create an example for better understanding. Let's say we have a class.
class Person {}
And we want to add a property. How do we do that? From what I read there are 2 ways:
class Person {myProperty ='Something'} //As shown at . If we use console.log(Person) the property will not show
Now let's create another class that extends Person, let's say Athlete and I want to change 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);
}
}
Now let's create a new object using Athlete as constructor
const athlete = new Athlete();
console.log(athlete)// It will have the property myProperty with value 'Something else'
My questions are:
- Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
- Why can I access myProperty inside writeSomething()?
- Why does myProperty appear inside athlete, when it didn't appear anywhere else?
- Is this another way of writing properties as opposed to Person.myProperty or is it something else?
Thank you,
Elanvi
I have a question about class properties. I'll create an example for better understanding. Let's say we have a class.
class Person {}
And we want to add a property. How do we do that? From what I read there are 2 ways:
class Person {myProperty ='Something'} //As shown at https://javascript.info/class. If we use console.log(Person) the property will not show
Now let's create another class that extends Person, let's say Athlete and I want to change 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);
}
}
Now let's create a new object using Athlete as constructor
const athlete = new Athlete();
console.log(athlete)// It will have the property myProperty with value 'Something else'
My questions are:
- Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
- Why can I access myProperty inside writeSomething()?
- Why does myProperty appear inside athlete, when it didn't appear anywhere else?
- Is this another way of writing properties as opposed to Person.myProperty or is it something else?
Thank you,
Elanvi
Share Improve this question asked Feb 6, 2020 at 16:20 elanvielanvi 711 silver badge6 bronze badges 6- 1 Sorry about this, instead of 'And we want to add a property. How do we do that? From what I read there are 2 ways:' consider 'And we want to add a property'. I wanted to pare this method with Person.myProperty in paralel but it got way to confusing so I simplified it and forgot to change. – elanvi Commented Feb 6, 2020 at 16:28
- Have a look at static properties here - developer.mozilla/en-US/docs/Web/JavaScript/Reference/… – Bloatlord Commented Feb 6, 2020 at 16:31
-
Hi yes, you can define a new instance variable using a syntax similar to how you defined
myProperty
. – IronMan Commented Feb 6, 2020 at 16:34 - Questions that enpass multiple questions are not a good fit for stack overflow. They are not likely to help others. Please create a more focused question. This look probably answers your questions – Ruan Mendes Commented Feb 6, 2020 at 16:43
- Thank you for your answers guys, I get it now. What I was asking about was basically Public instance fields, but I didn't know the term. As you mentioned documentation can be found at developer.mozilla/en-US/docs/Web/JavaScript/Reference/…. – elanvi Commented Feb 6, 2020 at 17:04
4 Answers
Reset to default 3First of all, they are not "class properties". They are instance properties just declared upfront. This gives you the clear idea about what fields (properties) can be expected from the class instance.
Based on the documentation:
Public and private field declarations are an experimental feature (stage 3) proposed at TC39, the JavaScript standards mittee. Support in browsers is limited, but the feature can be used through a build step with systems like Babel.
So, based on the proposal in the link, your code is for declaring public properties of the class instances:
class Person {
myProperty ='Something' // this means anyone can access the property
}
For private properties, they're suggesting this syntax:
class Person {
#myPrivateProperty ='Something' // this means only the instance methods have access
}
To answer your questions:
- Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
It's stored as an instance property of an instance of the Person
class. Since Athlete
extends it, an instance of Athlete
also will be given the same property. Read Object Oriented Programming for more details.
- Why can I access myProperty inside writeSomething()?
writeSomething()
is the method of the instance, so it has access to any instance property. (public and private)
- Why does myProperty appear inside athlete, when it didn't appear anywhere else?
It should appear in a Person
instance as well. For example, you can write:
const person = new Person();
person.myProperty = 'new Something';
- Is this another way of writing properties as opposed to Person.myProperty or is it something else?
It's just a declaration of instance properties made easier and more intuitive, and with implied access modifier (i.e. public
).
Finally, if you want to declare a class property, you need to specify it as a static
property like this:
class Person {
static myProperty = 'some value';
}
console.log(Person.myProperty);
I'll try to answer your questions as best I can:
- Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
Writing:
class Person { myProperty = 'Something' }
Is the same as writing:
class Person {
constructor() {
this.myProperty = 'Something';
}
}
My understanding is that writing it the first way actually adds the property definition to the constructor - you won't see myProperty
anywhere on the prototype of Person
, the property will not exist anywhere until an instance is created with new Person
and the constructor is called.
- Why can I access myProperty inside writeSomething()?
You can access myProperty
inside writeSomething
through the this
context as it will refer to the instance of Person
unless otherwise bound.
- Why does myProperty appear inside athlete, when it didn't appear anywhere else?
The property isn't inside of Athlete
per-se but without defining it's own constructor it will inherit the parent class constructor meaning Athlete
instances will get the same property defined when they are instantiated. If you were to add a constructor to Athlete
you would have to call the super
constructor (i.e. Person
constructor) at which time the property would be defined on the intstance.
- Is this another way of writing properties as opposed to Person.myProperty or is it something else?
As described above, you can also define these instance properties in the constructor with this.myProp = 'my value'
. You can read more here on how to use class fields.
Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
Public instance fields on classes are syntactic sugar for instantiating instance own properties from inside the class constructor.
class Person { constructor() { this.p1 = 'p1 value' } }
Given the following:
class Person { p1 = 'p1 value'; p2 = 'p2 value' }
class Athlete extends Person { p1 = 'p1 overridden value' }
The prototype
property of the Person
class is placed on to the prototype chain of the prototype
property of the Athlete
class.
console.log(Athlete.prototype.__proto__ === Person.prototype) // true
The prototype
property of the Person
class does not contain the p1
property, because it will be dynamically added by the default constructor of the Person
class, when an instance is created.
console.log(Person.prototype.hasOwnProperty('p1')) // false
const p = new Person()
When newing-up a Person
the constructor dynamically adds the property to the resulting instance.
console.log(p.hasOwnProperty('p1')) // true
const a = new Athlete()
When newing-up an Athlete
the Person
super constructor is implicitly called against the Athlete
instance putting both p1
and p2
on the instance, finally the Athlete
constructor is run and p1
is overwritten.
console.log(a.hasOwnProperty('p1')) // true
console.log(a.hasOwnProperty('p2')) // true
console.log(a.p1) // p1 value overridden
Why can I access myProperty inside writeSomething()?
This is just normal this
behavior. When invoking a function as a method, the target of the method is the object it was invoked upon. In this case, the instance of Athlete
.
1) Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
Variables that can be accessed inside Person
or Athlete
are called static
class variables. You can define them by either doing:
Person.staticProperty = 'Something';
or
class Person {
static staticProperty = 'Something';
}
This variable can be accessed inside your class:
class Person {
static staticProperty = 'Something';
logStaticProperty() {
console.log(Person.staticProperty);
}
}
2) Why can I access myProperty inside writeSomething()?
When you create an instance of a class using new
, you can attach variables that are isolated to that single instance. The syntax being used in the constructor attaches the variable to the instance.
3) Why does myProperty appear inside athlete, when it didn't appear anywhere else?
See #2.
4) Is this another way of writing properties as opposed to Person.myProperty or is it something else?
Using the constructor
method is functionally equivalent
class Person {
constructor() {
this.myProperty = 'Somethin';
}
}