Javascript闭包-有什么负面影响?
问题: 闭包似乎有很多好处,但有什么坏处(内存泄漏?混淆问题?带宽增加?)?此外,我对闭包的理解正确吗?最后,一旦创建了闭包,它们可以被销毁吗 我已经读了一些关于Javascript闭包的文章。我希望有一个稍有见识的人来指导我的主张,纠正我的错误 闭包的好处:Javascript闭包-有什么负面影响?,javascript,closures,Javascript,Closures,问题: 闭包似乎有很多好处,但有什么坏处(内存泄漏?混淆问题?带宽增加?)?此外,我对闭包的理解正确吗?最后,一旦创建了闭包,它们可以被销毁吗 我已经读了一些关于Javascript闭包的文章。我希望有一个稍有见识的人来指导我的主张,纠正我的错误 闭包的好处: 使用内部函数将变量封装到局部范围。 函数的匿名性无关紧要 我发现有帮助的是做一些关于本地/全局范围的基本测试: <script type="text/javascript"> var global_text = ""
<script type="text/javascript">
var global_text = "";
var global_count = 0;
var global_num1 = 10;
var global_num2 = 20;
var global_num3 = 30;
function outerFunc() {
var local_count = local_count || 0;
alert("global_num1: " + global_num1); // global_num1: undefined
var global_num1 = global_num1 || 0;
alert("global_num1: " + global_num1); // global_num1: 0
alert("global_num2: " + global_num2); // global_num2: 20
global_num2 = global_num2 || 0; // (notice) no definition with 'var'
alert("global_num2: " + global_num2); // global_num2: 20
global_num2 = 0;
alert("local_count: " + local_count); // local_count: 0
function output() {
global_num3++;
alert("local_count: " + local_count + "\n" +
"global_count: " + global_count + "\n" +
"global_text: " + global_text
);
local_count++;
}
local_count++;
global_count++;
return output;
}
var myFunc = outerFunc();
myFunc();
/* Outputs:
**********************
* local_count: 1
* global_count: 1
* global_text:
**********************/
global_text = "global";
myFunc();
/* Outputs:
**********************
* local_count: 2
* global_count: 1
* global_text: global
**********************/
var local_count = 100;
myFunc();
/* Outputs:
**********************
* local_count: 3
* global_count: 1
* global_text: global
**********************/
alert("global_num1: " + global_num1); // global_num1: 10
alert("global_num2: " + global_num2); // global_num2: 0
alert("global_num3: " + global_num3); // global_num3: 33
</script>
var global_text=“”;
var全局计数=0;
var global_num1=10;
var global_num2=20;
var global_num3=30;
函数outerFunc(){
var local_count=local_count | 0;
警报(“global_num1:+global_num1);//global_num1:未定义
var global_num1=global_num1 | 0;
警报(“全局num1:+global num1);//全局num1:0
警报(“全局num2:+global num2);//全局num2:20
global_num2=global_num2 | | 0;/(注意)没有带“var”的定义
警报(“全局num2:+global num2);//全局num2:20
全局μnum2=0;
警报(“本地计数:+local计数);//本地计数:0
函数输出(){
全局_num3++;
警报(“本地\u计数:“+local\u计数+”\n”+
全局计数:“+全局计数+”\n+
“全局文本:“+全局文本”
);
本地_计数++;
}
本地_计数++;
全局_计数++;
返回输出;
}
var myFunc=outerFunc();
myFunc();
/*产出:
**********************
*本地人口:1
*全球人口总数:1
*全局文本:
**********************/
全局\ u text=“全局”;
myFunc();
/*产出:
**********************
*本地人口:2
*全球人口总数:1
*全局文本:全局
**********************/
var局部计数=100;
myFunc();
/*产出:
**********************
*本地人口:3
*全球人口总数:1
*全局文本:全局
**********************/
警报(“全局num1:+全局num1);//全球数字1:10
警报(“全局num2:+全局num2);//全球人口:0
警报(“全局num3:+全局num3);//全球人口:33
我从中得到了一些有趣的东西:
vol7ron你可能会得到一大堆好答案。一个肯定的负面因素是Internet Explorer循环引用内存泄漏。基本上,JScript不认为DOM对象的“循环”引用是可收集的。使用闭包很容易创建IE认为的循环引用。第二个链接中提供了几个示例
IE6的建议解决方法(除了终止进程!)是不要使用闭包。闭包可能会导致内存泄漏,但Mozilla已尝试优化其垃圾收集引擎以防止这种情况 我不确定Chrome如何处理闭包。我认为它们和Mozilla相当,但我不想肯定。IE8显然比IE的早期版本有所改进——它几乎是一款全新的浏览器,但仍有一些细微差别
您还应该对代码进行基准测试,看看在速度方面是否有任何改进。闭包带来了很多好处……但也带来了一些好处
function ScopeIssues(count) {
var funcs = [];
for (var i = 0; i < count; ++i) {
funcs[i] = function() { console.log(i); }
}
return funcs;
}
x = ScopeIssues(10);
x[0](); // outputs 10
x[1](); // does too
x[2](); // same here
x[3](); // guess
function Corrected(count) {
var funcs = [];
for (var i = 0; i < count; ++i) {
(function(which) {
funcs[i] = function() { console.log(which); };
})(i);
}
return funcs;
}
x = Corrected(10);
x[0](); // outputs 0
x[1](); // outputs 1
x[2](); // outputs 2
x[3](); // outputs 3
function WorksToo(count) {
var funcs = [];
for (let i = 0; i < count; ++i) {
funcs[i] = function() { console.log(i); }
}
return funcs;
}
x = WorksToo(10);
x[0](); // outputs 0
x[1](); // outputs 1
x[2](); // outputs 2
x[3](); // outputs 3
value = 'global variable';
function A() {
var value = 'local variable';
this.value = 'instance variable';
(function() { console.log(this.value); })();
}
a = new A(); // outputs 'global variable'
function A() {
var self = this;
this.value = 'some value';
(function() { console.log(self.value); })();
}
function X() {
var self = this;
var Y = function() {
var outer = self;
var self = this;
};
}
function X() {
var self, Y;
self = this;
Y = function() {
var outer, self;
outer = self;
self = this;
};
}