I've been using Javascript closures to protect variables by making them local to the returned functions, such as:
closure = function() {
var secretVar = 'Secret';
return {
"msg" : function() {
console.log(secretVar);
}
};
}();
console.log(closure.secretVar); // Undefined
closure.msg(); // Secret
I feel that I have a pretty good grasp of that, giving me the ability to control how inner variables are accessed if at all.
I'm now running into this problem
closure = function() {
var secretVar = ['Secret One','Secret Two'];
return {
"del" : function(modMe) {
modMe = secretVar;
modMe.slice(1,1);
console.log(modMe);
}(secretVar),
"secretVar" : function() {
console.log(secretVar);
}
};
}();
closure.del(); // Secret One
closure.secretVar(); // Secret One
I want closure.del() to return Secret One, but I want the secretVar to remained untouched, however, it's not. The del() function is modifying the reference rather than a copy, and I'm unsure of how to get it to copy secretVar and modify that.
I'm guessing it's going to be in the form of
(function(y) {
//..Body that changes y
})(secretVar)
but I haven't been able to get that to work. Any ideas?
Your problem actually has nothing to do with closures. When you do:
modMe = secretVar;
You are just creating a new variable pointing to the same array. What you do to one will be reflected in both variables, since they are pointing to the same thing.
If you want to perform some sort of modification on the array (while maintaining the original), you need to copy it first:
var copied = [];
for(var i = 0; i < secretVar.length; i++){
copied.push(secretVar[i]);
}
Edit: As an aside, when you say you are using closures to "protect variables" you're not protecting them from being modified by the returned functions that performed the closure. You just made it so that the variable is inaccessible from outside the scope of those functions. But, inside the scope, such as when you do your slice, the variable is there and accessible to that function and is not "protected" just because it is a closure.
Edit 2: If you are going to be copying the array frequently, you can eliminate some of the irritation of the iteration by creating a closured function to do the copying for you:
closure = function() {
var secretVar = 'Secret';
var clone = function(){
var clonedArr = [];
var length = secretVar.length;
for(var i = 0; i < length; i++){
clonedArr.push(secretVar[i]);
}
return clonedArr;
}
return {
"msg" : function() {
var duplicate = clone();
}
};
}();
Very close -- the form is:
(function(y) {
return function() {
// that changes y
};
})(secretVar)
NOTE: This will still pass a reference, and any destructive or altering operations will still affect secretVar
. You'll need to make a deep copy of secretVar
if you want to avoid altering it.
SEE: http://jsfiddle.net/B3ryr/2/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With