I've built a program that tracks grades in a school, and which students belong to each grade. One of the class's methods, roster()
, returns the school roster after it sorts the students alphabetically. In the tests, I'm trying to see if the school roster can be modified outside of the class, specifically by calling roster()
, storing this object, and modifying it. This is possible because JavaScript is returning a reference to my this._roster
object. For the test to pass, I must be unable to modify the returned object.
Credit: I'm working on a project from exercism.io
Here's my code:
export class GradeSchool {
constructor() {
this._roster = {};
}
roster() {
const keys = Object.keys(this._roster);
for (let i = 0; i < keys.length; i++) {
this._roster[keys[i]].sort();
}
return this._roster;
}
add(name, grade) {
if(this._roster.hasOwnProperty(grade)) {
this._roster[grade].push(name);
} else {
this._roster[grade] = [name];
}
}
}
And my test:
test('roster cannot be modified outside of module', () => {
school.add('Aimee', 2);
const roster = school.roster();
roster[2].push('Oops.');
const expectedDb = { 2: ['Aimee'] };
expect(school.roster()).toEqual(expectedDb);
});
I tried modifying my roster()
as shown: ... which technically no longer modifies the this._roster
object, but obviously still doesn't work as it stills passes an object by reference, which is stored and modified outside of the module.
roster() {
const duplicateRoster = {};
const keys = Object.keys(this._roster);
for (let i = 0; i < keys.length; i++) {
duplicateRoster[keys[i]] = this._roster[keys[i]].sort();
}
return duplicateRoster;
}
I've been researching how I can return an object by value and not by reference. I've been unsuccessful in finding an answer, however. If somebody knows how, please show me here. If it isn't possible, can somebody please explain how I can make my this._roster
object private/unaccessible outside of the module?