Reputation: 1533
I think I've misunderstood something about OOP in JavaScript. As I understand it, the point of setting up a private variable with its own getter and setter functions is to protect it from accidental alteration elsewhere in the program. But I'm finding it very easy to accidentally change private variables using their getter functions, which means I must be doing something wrong.
function Phone(os) {
this.os = os;
var _phoneBook = []; // phoneBook is intended to be private
this.newNumber = function(phoneNumber) { // set new number
_phoneBook.push(phoneNumber);
}
this.listNumbers = function() { // get all numbers
return _phoneBook;
}
}
var andy = new Phone("Android");
andy.newNumber("555-123-4567");
console.log(andy.listNumbers()); // => ["555-123-4567"]
// You shouldn't be able to set a private property through a getter function, but you can.
var extendedPhoneBook = andy.listNumbers().push("123-456-7890");
console.log(andy.listNumbers()); // => ["555-123-4567", "123-456-7890"]
Upvotes: 2
Views: 416
Reputation: 111
That Array is being passed as a reference, so when calling listNumbers()
you are returning the Actual Array to the exterior. You can return copies of the Array with something like this:
function Phone(os) {
this.os = os;
var _phoneBook = []; // phoneBook is intended to be private
this.newNumber = function(phoneNumber) { // set new number
_phoneBook.push(phoneNumber);
}
this.listNumbers = function() { // get all numbers
return _phoneBook.slice(0);
}
}
Upvotes: 2
Reputation: 14565
you might consider changing function listNumbers
to something like enumerateNumbers
that takes a function that gets passed a string for each number in your list to hide the internal array, something like this:
function Phone(os) {
this.os = os;
var _phoneBook = []; // phoneBook is intended to be private
this.newNumber = function(phoneNumber) { // set new number
_phoneBook.push(phoneNumber);
}
this.enumerateNumbers = function(cb) { // get all numbers
for (var idx in _phoneBook) {
cb(_phoneBook[idx]);
}
}
}
var andy = new Phone("Android");
andy.newNumber("555-123-4567");
andy.enumerateNumbers(function(num) { console.log(num); })
Upvotes: 0