最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Class Property in JavaScript - Stack Overflow

programmeradmin1浏览0评论

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:

  1. Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
  2. Why can I access myProperty inside writeSomething()?
  3. Why does myProperty appear inside athlete, when it didn't appear anywhere else?
  4. 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:

  1. Where is myProperty stored, I can't find it anywhere inside Person or Athlete?
  2. Why can I access myProperty inside writeSomething()?
  3. Why does myProperty appear inside athlete, when it didn't appear anywhere else?
  4. 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
 |  Show 1 more ment

4 Answers 4

Reset to default 3

First 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:

  1. 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.

  1. 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)

  1. 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';
  1. 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:

  1. 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.

  1. 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.

  1. 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.

  1. 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';
  }
}
发布评论

评论列表(0)

  1. 暂无评论