“The behavior property is always initialized to zero.”

Under this.name , we create a property called behavior , which will keep track of the number of times a dog misbehaves. The behavior property is always initialized to zero.

does this mean behavior is sought of a constant when creating a class… making reference to “The behavior property is always initialized to zero.”

implies a counter or accumulator, so no, it won’t be a constant. In the constructor it is a literal so that the variable has a numeric value that we can do arithmetic with.

1 Like

Sorry did not make my statement clear… What i meant was that, in creating classes, is it always important to include behaviour since the statement says ‘always’

link below
https://www.codecademy.com/courses/introduction-to-javascript/lessons/classes/exercises/constructor-method

Please post a link to the exercise page so we can get some context. always is a pretty vague term without it.

1 Like

Notice, we also prepended our property names with underscores ( _name and _behavior ), which indicate these properties should not be accessed directly.

This statement is wild to me, i guese i did not understand it properly when it got introduced at first… can i get a slightly deeper explanation on whyit should not be accesssed directly…
link below
https://www.codecademy.com/courses/introduction-to-javascript/lessons/classes/exercises/methods

class Dog {
  constructor(name) {
    this._name = name;
    this._behavior = 0;
  }
  get name() {
    return this._name;
  }
  get behavior() {
    return this._behavior;
  }
  incrementBehavior() {
    this._behavior++;
  }
}

Above we do not need to directly access the instance properties since we have an accessor (get) that returns it. The syntax is the same as for plain objects.

rex = new Dog('Rex')
console.log(rex.name)        //  Rex
console.log(rex.behavior)    //  0
rex.incrementBehavior()
console.log(rex.behavior)    //  1
1 Like

So how special or important is it to allow get to be the one to access it

It’s special in that we can use standard syntax to poll the property value. Important in that we force our program to respect this construct.

We’ll see in lessons that we can apply program logic in the process. Normally we could not give this added behavior to the actual property. That’s an important feature.

class Dog {
  constructor (name) {
    this._name = name;
    this._behavior = 0;
    this._class = this.constructor.name
  }
  get name () {
    return `My name is ${this._name}, and I'm a ${this.class}.`
  }
  get behavior () {
    return `I'm a ${['great', 'good', 'naughty'][this._behavior % 3]} dog.`
  }
  get class () {
    return this._class
  }
  incrementBehavior () {
    this._behavior++;
  }
}
rex = new Dog('Rex')
console.log(rex.name)
console.log(rex.behavior)
rex.incrementBehavior()
console.log(rex.behavior)
rex.incrementBehavior()
console.log(rex.behavior)
My name is Rex, and I'm a Dog.
I'm a great dog.
I'm a good dog.
I'm a naughty dog.

and down the rabbit hole we go…

class Dog {
  constructor (name='Rex') {
    this._name = name;
    this._behavior = 0;
    this._class = this.constructor.name
  }
  get name () {
    return `My name is ${this._name}, and ${this.behavior}`
  }
  get behavior () {
    return `I'm a ${this.grade(this._behavior)} ${this.class}.`
  }
  get class () {
    return this._class
  }
  incrementBehavior () {
    this._behavior++;
  }
  grade (x=0) {
    return ['great', 'good', 'naughty'][x % 3]
  } 
}
rex = new Dog()
console.log(rex.name)
rex.incrementBehavior()
console.log(rex.name)
rex.incrementBehavior()
console.log(rex.name)
console.log(new Dog().grade(2))
My name is Rex, and I'm a great Dog.
My name is Rex, and I'm a good Dog.
My name is Rex, and I'm a naughty Dog.
naughty

This permits instantiation without an argument:

constructor (name='Rex') {

Here, in the name getter we use the behavior getter, and not a direct reference to the main property. The only direct reference is to, this._name.

  get name () {
    return `My name is ${this._name}, and ${this.behavior}`
  }

Here, in the behavior getter we use the class getter, likewise not a direct reference to its main property. The only direct reference is to, this._behavior.

  get behavior () {
    return `I'm a ${this.grade(this._behavior)} ${this.class}.`
  }
this._class = this.constructor.name

Suffice it to say that it reads fairly self-evident but this is all new, no doubt. It will likely be a while before you delve under the hood of JS but this is an appropriate introduction. The rest is up for more reading. One shouldn’t get too hung up on it just now. All we’ve done is peer into the constructor property of this new instance and get the name of the class.

  grade (x=0) {
    return ['great', 'good', 'naughty'][x % 3]
  } 

That method is also quite self-documenting. It will return one of the three string objects so long as an integer is given. It has a default of 0 which means if there is no argument, the first string will be returned.

We can call this method on a transient instance…

console.log(new Dog().grade(1))    //  great

Remember, .name is 'Rex'.

The point is that there is a valid use case for get and set, though it is one to partially justify, and then adhere to once in place. No direct references to the main properties (otherwise known as backing variables) should appear anywhere in the program.

The only place a getter will not work is within itself or within is companion setter, where applicable. Also, the property name cannot be the same as the getter. These will create a circular reference (infinite loop). Those underscores are critical which is why we need to confine them to getter and setter only.

1 Like