Why when we have this
function Car() {
const fuel = 50
return {
fuel,
}
}
const car = Car()
console.log(car.fuel) // 50
car.fuel = 3000
console.log(car.fuel) // 3000
And if we add a getter, the fuel property cannot be muted:
function Car() {
const fuel = 50
return {
get fuel() {
return fuel
},
}
}
const car = Car()
car.fuel = 3000
console.log(car.fuel) // 50
But then, if I try it on an isolated object it doesn't work the same way:
const person = {
_firstName: 'John',
_lastName: 'Doe',
get fname() {
return this._firstName;
}
}
console.log(person.fname); // prints 'John'
person._firstName = 'Juan';
console.log(person.fname); //prints 'Juan'
Context: I was trying to figure out why setters exist, I couldn't wrap around the idea of it usefulness. I get why setters have a place. So I found this code snippet explaining that one of the advantages was to keep properties safe from changes. Reference here.
When you're doing
function Car() {
const fuel = 50
return {
fuel,
}
}
const car = Car()
Car()
is just returning { fuel: 50 }
, a plain object.
So when you set car.fuel = 3000
, it just changes to { fuel: 3000 }
.
Let's take a look at the second case.
function Car() {
const fuel = 50
return {
get fuel() {
return fuel
},
}
}
const car = Car()
Let me rename fuel
and fuel()
for clarity:
function Car() {
const a = 50
return {
get b() {
return a
},
}
}
const car = Car()
Here, when you do car = Car()
, you can understand it as car = { get b(): {return a} }
. When you define a getter function like this, you cannot change it.
So when you do car.b = 3000
, JS is saying "Oh, you're trying to change the value of b
, but that is a getter function, you're not allowed to change it." JS being JS, it doesn't throw you an error though.
const person = {
_firstName: 'John',
_lastName: 'Doe',
get fname() {
return this._firstName;
}
}
console.log(person.fname); // prints 'John'
person._firstName = 'Juan';
console.log(person.fname); //prints 'Juan'
This one is pretty self evident, person._firstName
is just plain old any other property in an object, so you can change it however you want. But, similarly to the second case, if you try this:
const person = {
_firstName: 'John',
_lastName: 'Doe',
get fname() {
return this._firstName;
}
}
console.log(person.fname); // prints 'John'
person.fname = 'Juan';
console.log(person.fname); //prints 'John'
It will not change fname
.