Javascript 闭包,维护外部对象
我一直在使用 Javascript 闭包来保护变量,方法是将它们设置为返回函数的本地变量,例如:
closure = function() {
var secretVar = 'Secret';
return {
"msg" : function() {
console.log(secretVar);
}
};
}();
console.log(closure.secretVar); // Undefined
closure.msg(); // Secret
我觉得我对此有很好的掌握,使我能够控制内部变量的访问方式(如果有的话)。
我现在遇到这个问题,
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
我希望closure.del()返回Secret One,但我希望secretVar保持不变,然而,事实并非如此。 del() 函数正在修改引用而不是副本,我不确定如何让它复制 SecretVar 并修改它。
我猜它会以以下形式出现,
(function(y) {
//..Body that changes y
})(secretVar)
但我还没能让它发挥作用。有什么想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你的问题实际上与闭包无关。当您这样做时:
您只是创建一个指向相同数组的新变量。您对一个变量所做的操作将反映在两个变量中,因为它们指向同一事物。
如果您想对数组执行某种修改(同时保留原始数组),您需要先复制它:
编辑:顺便说一句,当您说您使用闭包来“保护变量”时,您并没有保护它们防止被执行闭包的返回函数修改。您刚刚做到了这一点,以便从这些函数的范围之外无法访问该变量。但是,在作用域内,例如当您执行切片时,该变量就在那里并且可供该函数访问,并且不会仅仅因为它是一个闭包而受到“保护”。
编辑 2:如果您要经常复制数组,您可以通过创建一个封闭函数来为您进行复制来消除迭代的一些麻烦:
Your problem actually has nothing to do with closures. When you do:
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:
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:
非常接近——形式为:
注意:这仍然会传递引用,任何破坏性或改变操作仍然会影响
secretVar
。如果您想避免更改,则需要制作secretVar
的深层副本。请参阅:http://jsfiddle.net/B3ryr/2/
Very close -- the form is:
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 ofsecretVar
if you want to avoid altering it.SEE: http://jsfiddle.net/B3ryr/2/
Robert 做了很好的评论,但也要注意
closure.del
不是一个函数,而是未定义的。再看看你的代码。该函数会自动执行并且不返回任何内容,因此 del 将不会返回任何内容。一般是这样的形式:
Robert made a good comment, but also note that
closure.del
is not a function, but undefined. Take another look at your code. The function is automatically executed and returns nothing, so del will be nothing.It's generally this form:
您的
function(modMe) { ... }(secretVar)
表达式实际上返回一个值而不是函数,因为您正在执行该函数。结合马特的答案,您需要:(secretVar)
组件以及modMe
参数 - 该函数已经可以访问secretVar无论如何。
Your
function(modMe) { ... }(secretVar)
expression is actually returning a value and not a function, since you are executing the function. Coupled with Matt's answer, you need to:(secretVar)
component from the expression as well as themodMe
parameter -- the function already has access tosecretVar
anyway.