If we return arr
, arr
can be mutated. Does returning a copy of arr
allow for more data privacy?
Original code
function foo() {
let arr = [];
function qux() {
return arr;
}
return {
qux,
}
}
let qux = foo().qux;
qux();
Revised code. Here qux
returns arr.slice()
, a copy of arr
instead of reference to original array.
function foo() {
let arr = [];
function qux() {
return arr.slice();
}
return {
qux,
}
}
let qux = foo().qux;
qux();
CodePudding user response:
"Private" is not the right word to use. Whether you slice the array before returning or not, the caller of the function will still be able to see the contents of what's returned. The caller can also examine the foo
function itself by calling .toString
on it. If you want actual privacy, function implementation hiding is at stage 2 and has a possibility of eventually being integrated into the language, but isn't here yet.
With your code, slicing does make the data more controllable - it means that, if you plan to use the array later inside foo
, your module doesn't need to rely on the caller of the function not mutating the array.
That said, most would say that returning copies of objects everywhere they're returned is quite overly defensive. It'd be easier to say that consumers of your function/library should follow the implicit standard of avoid mutating objects you don't own unless explicitly permitted. If I'm using a library, and I get an object returned from the library, and I mutate it and the object (or something associated with the object) stops working as a result - that's on me, not the library.
CodePudding user response:
By "keeping private" I assume you mean that the array in the object cannot be changed from the outside, e.g. must remain immutable. To assure this in your qux()
method you can do a deep copy. There are several ways to do a deep copy of an array with objects. The easiest one (not necessarily the fastest one) is a JSON stringify and parse:
function qux() {
return JSON.parse(JSON.stringify(arr));
}