Consider we have follow snippets:
function Counter() {
let count = 0
function inc() {
count += 1
}
function dec() {
count -= 1
}
function getCount() {
return count
}
return { getCount, inc, dec, count }
}
const counter = Counter()
counter.inc()
counter.inc()
console.log(counter.getCount()) // 2
console.log(counter.count) // 0
I am wondering why using function getCount()
and directly return count
variable shows different result. In my opinion they both reference the same count
address, and after inc()
calls its value should be altered accordingly.
return { getCount, inc, dec, count }
:
When you change the value of the count
variable you do not change the value of the count
property.
The reason is because when you do counter.count
, you are getting the count value off the of the new object you returned. That count is actually a copy of the value at the time it was created and will never get updated.
If instead, you create a class and use this.count
instead, it'll always be updated.
class Counter {
constructor() {
this.count = 0;
}
inc() {
this.count += 1;
}
dec() {
this.count -= 1;
}
getCount() {
return this.count;
}
}
const counter = new Counter();
counter.inc()
counter.inc()
console.log(counter.getCount()) // 2
console.log(counter.count) // 2
Or, if you want to do it the more old-school way:
function Counter() {
this.count = 0
function inc() {
count += 1
}
function dec() {
count -= 1
}
function getCount() {
return count
}
this.inc = inc;
this.dec = dec;
this.getCount = getCount;
return this;
}
const counter = Counter()
counter.inc()
counter.inc()
console.log(counter.getCount()) // 2
console.log(counter.count) // 2
Or, you could make count
and object with some value that would get updated:
function Counter() {
let count = { value: 0 }
function inc() {
count.value += 1
}
function dec() {
count.value -= 1
}
function getCount() {
return count.value
}
return { getCount, inc, dec, count }
}
const counter = Counter()
counter.inc()
counter.inc()
console.log(counter.getCount()) // 2
console.log(counter.count.value) // 2
Though that last one is a bit silly for this particular use-case.