Reputation: 249
I am evaluating a way of use the Singleton Pattern called Monostate in JavaScript.
I have some code like the following:
class Boss {
get name() { return Boss._name }
set name(value) {
Boss._name = value;
}
get age() { return Boss._age }
set age(value) {
Boss._age = value
}
toString() {
return `
Boss' name is ${this.name}
and he is ${this.age} years old.
`
}
}
Boss._age = undefined;
Boss._name = undefined;
But I am not deeply understanding the difference between the Class scope vs the Instance scope
I mean if I make the following:
let boss = new Boss();
boss.name = 'Bob';
boss.age = 55;
let boss2 = new Boss();
boss2.name = 'Tom';
boss2.age = 33;
console.log(boss.toString());
console.log(boss2.toString());
I will always get the data of the second instance with name Tom
, but why?
Boss' name is Tom and he is 33 years old.
Upvotes: 3
Views: 436
Reputation: 5941
Use this
instead of the class name Boss
to refer to the object instance from within the class definition:
class Boss {
get name() {
return this._name
}
set name(value) {
this._name = value;
}
get age() {
return this._age
}
set age(value) {
this._age = value
}
toString() {
return `
Boss' name is ${this.name}
and he is ${this.age} years old.
`
}
}
const b1 = new Boss();
b1.name = 'Tom';
b1.age = 55;
const b2 = new Boss();
b2.name = 'Bill';
b2.age = 33;
console.log(b1.toString());
console.log(b2.toString());
The Boss
you are referring to in your code is actually the constructor when you really want the instance.
Upvotes: 0
Reputation: 21130
The reason this behaviour happens is due the fact that instances of Boss
refer to the same Boss
object to set and read their values. Instances of Boss
set the _name
and _age
value on Boss
. When reading from these instance attributes, the last value set is returned.
You can see this by the value of Boss._name
that changes every time a an instance of Boss
sets their name. After boss.name = 'Bob'
the value of Boss._name
will be 'Bob'
. After setting boss2.name = 'Tom'
the value of Boss._name
will be 'Tom'
.
I've added a snippet that hopefully displays the troubling behaviour better. In the scenario below boss1
and boss2
have their own storage while boss3
and boss4
share their storage (you use the Boss
object as storage).
class Boss {
constructor(storage) {
this.storage = storage || {};
}
get name() {
return this.storage.name;
}
set name(value) {
this.storage.name = value;
}
}
var boss1 = new Boss(),
boss2 = new Boss(),
sharedStorage = {},
boss3 = new Boss(sharedStorage),
boss4 = new Boss(sharedStorage);
boss1.name = "a";
boss2.name = "b";
boss3.name = "c";
boss4.name = "d";
console.log(boss1.name, boss2.name, boss3.name, boss4.name);
Upvotes: 2
Reputation: 36574
Boss
doesn't refer to instance of class it will refer to the constructor function Boss
which is only one in the whole code. In the methods you are adding property not to the instance but the constructor.
You need to use this
to access the instance inside the method of an object.
class Boss {
get name() { return this._name }
set name(value) {
this._name = value;
}
get age() { return this._age }
set age(value) {
this._age = value
}
}
let boss = new Boss();
boss.name = 'Bob';
boss.age = 55;
let boss2 = new Boss();
boss2.name = 'Tom';
boss2.age = 33;
console.log(boss2.name);
console.log(boss.name);
Upvotes: 0