[Easy] LeetCode JS 30 - 2665. Counter II
March 5, 2024
LeetCode 30 Days of JavaScript
This question is from LeetCode's 30 Days of JavaScript Challenge
2665. Counter IIQuestion Prompt
Imagine you're working on a project that requires tracking various metrics. We need a flexible way to manage counters within our code. Your task is to design a function called createCounter
that can be used to generate custom counters with specific starting values.
createCounter
will return an object with the following method
get()
: Returns the current value of the counter.increment()
: Increments the counter by 1 and returns the updated value.decrement()
: Decrements the counter by 1 and returns the updated value.reset()
: Resets the counter back to its initial value.
const counter = createCounter(4);
counter.get(); // 4
counter.increment(); // 5
counter.increment(); // 6
counter.get(); // 6
counter.reset(); // 4
counter.decrement(); // 3
Solutions
Looking to practice more questions like these? We recommend GreatFrontEnd, the best platform for honing your frontend interview skills!
The createCounter
function creates a counter object with methods for getting, incrementing, decrementing, and resetting its value. The key to its functionality lies in how it utilizes closures.
Firstly, the function defines a variable value
with the optional initialValue
argument. This variable holds the current counter value and is kept private within the function scope.
Then, it defines four inner functions: get
, increment
, decrement
, and reset
. These functions form the closure. Each function can access the private value
variable due to JavaScript's lexical scoping rules. Even though the outer createCounter
function may have already returned, the inner functions still retain access to its variables due to the closure.
get
simply returns the current value ofvalue
.increment
increasesvalue
by 1 and returns the updated value.decrement
decreasesvalue
by 1 and returns the updated value.reset
setsvalue
back to its initial value and returns it.
Finally, the createCounter
function returns an object containing only the inner functions (get
, increment
, decrement
, and reset
) as properties. This returned object acts as the counter interface, exposing the necessary methods while keeping the internal value private and protected from outside modifications.
In essence, the closure ensures that the inner functions always have access to the current counter value, even after the outer function has finished executing. This is crucial for maintaining the counter's state and allowing users to manipulate it through the exposed methods
function createCounter(initialValue = 0) {
let value = initialValue;
function get() {
return value;
}
function increment() {
value += 1;
return value;
}
function decrement() {
value -= 1;
return value;
}
function reset() {
value = initialValue;
return value;
}
return {
get,
increment,
decrement,
reset,
};
}
Or we can rewrite using class
. The key here is the this
keyword in JavaScript. In JavaScript, the this
keyword refers to the current object context. Its value depends on how the function is called or the object is used.
In the Counter
class, the this
keyword inside the constructor, methods, and createCounter
function refers to the counter object instance being created or used. This allows you to access and modify the object's properties (this.value
and this.initialValue
) within these methods.
Constructor:
- The
constructor
function is used to initialize a newCounter
object. - It takes an optional
initialValue
argument, which defaults to 0. - Inside the constructor, the
this.initialValue
andthis.value
properties are set using theinitialValue
argument. - The
this
keyword here refers to the newly created counter object instance. It's used to assign the initial value to the object's properties.
Methods:
- The
get
method returns the current value of the counter. - The
increment
method increments the counter's value by 1 and returns the new value. - The
decrement
method decrements the counter's value by 1 and returns the new value. - The
reset
method resets the counter's value to its initial value and returns the new value. - In all of these methods, the
this
keyword refers to the current counter object instance. It's used to access and modify the object's properties (this.value
andthis.initialValue
).
Then, for createCounter
, takes an optional initialValue
argument and returns a new Counter
object initialized with that value. Inside the function, the new Counter(initialValue)
expression creates a new instance of the Counter
class using the initialValue
argument.
Noted that the this
keyword inside the Counter
class constructor refers to the newly created counter object, not the createCounter
function itself. So we directly return the new instance.
class Counter {
constructor(initialValue = 0) {
this.initialValue = initialValue;
this.value = initialValue;
}
get() {
return this.value;
}
increment() {
this.value += 1;
return this.value;
}
decrement() {
this.value -= 1;
return this.value;
}
reset() {
this.value = this.initialValue;
return this.value;
}
}
function makeCounter(initialValue = 0) {
return new Counter(initialValue);
}