I am writing a class where I have some data(it could be up to 100K) in form of an array. The data has to be added in a LIFO manner.
class AddProximityValues {
#values = [];
getValues () {
return this.#values;
}
setValues(...elements) {
this.#values.push(...elements);
}
//tried this way not sure
// if this is the right way of doing this
getValueEff() {
return [...this.#values]
}
}
const addProximityValues = new AddProximityValues();
console.log(addProximityValues.setValues(...[10, 20, 40]));
console.log(addProximityValues.getValues().push(50)); // don't want push to work
console.log(addProximityValues.getValues());
console.log('*********************************');
console.log(addProximityValues.getValueEff().push(50)); // don't want push to work
console.log(addProximityValues.getValues());
From the code when I return the array, it returns the reference and you can write values to it without calling the class function. I want that only the class method can update the values.
One way of doing this is returning a new array from the existing values, but it will take more memory if the array is too big. Is there any way to achieve it in a more efficient way?
CodePudding user response:
One option is not to have getValues
return an array at all. It could return an array iterator (or you could even make your class iterable by adding a [Symbol.iterator]
function). An iterator provides sequential access to the array values without allowing modification of the array. You could also provide a method for getting a value for a given index, and perhaps even a length
property:
class AddProximityValues {
#values = [];
[Symbol.iterator]() {
// Return an iterator for the values
return this.#values[Symbol.iterator]();
}
get(index) {
return this.#values[index];
}
get length() {
return this.#values.length;
}
setValues(...elements) {
this.#values.push(...elements);
}
}
const addProximityValues = new AddProximityValues();
addProximityValues.setValues(...[10, 20, 40]);
// This would fail, no `push` on an iterator
// console.log(addProximityValues.getValues().push(50)); // don't want push to work
// The code using it can loop through
for (const value of addProximityValues) {
console.log(value);
}
console.log(`Value at index 2: ${addProximityValues.get(2)}`);
console.log(`There are ${addProximityValues.length} values`);
// The code can still get all the values as an array if it really needs to
console.log([...addProximityValues]);