面试题答案
一键面试闭包对变量生命周期的影响
在TypeScript中,闭包会延长其捕获变量的生命周期。当一个函数内部定义了另一个函数,并且内部函数可以访问外部函数的变量时,就形成了闭包。外部函数执行完毕后,其变量本应被销毁,但由于闭包的存在,这些变量依然被引用,所以不会被垃圾回收机制回收,从而延长了变量的生命周期。
代码示例 - 利用闭包管理变量访问和生命周期
function outerFunction() {
let privateVariable = 0;
function innerFunction() {
privateVariable++;
return privateVariable;
}
return innerFunction;
}
const counter = outerFunction();
console.log(counter()); // 输出 1
console.log(counter()); // 输出 2
在上述代码中,outerFunction
返回了innerFunction
。innerFunction
形成了一个闭包,它可以访问并修改outerFunction
中的privateVariable
。尽管outerFunction
已经执行完毕,但privateVariable
因为被innerFunction
(闭包)引用,所以其生命周期被延长。
闭包内变量何时被垃圾回收机制回收
闭包内变量在不再被任何引用指向时,会被垃圾回收机制回收。例如:
function outerFunction() {
let privateVariable = 0;
function innerFunction() {
privateVariable++;
return privateVariable;
}
return innerFunction;
}
let counter = outerFunction();
console.log(counter()); // 输出 1
// 将counter设置为null,不再有对闭包的引用
counter = null;
// 此时,闭包内的privateVariable将可以被垃圾回收
当counter
被设置为null
后,就不再有对闭包(innerFunction
)的引用,闭包所引用的privateVariable
也不再被任何活动对象引用,因此垃圾回收机制可以回收相关内存。
可能导致内存泄漏的情况
- 循环引用:如果闭包内部存在对外部对象的循环引用,可能导致内存泄漏。例如:
function outerFunction() {
const largeObject = { data: new Array(1000000).fill(0) };
function innerFunction() {
// 假设这里的操作建立了循环引用
largeObject.referenceToInner = innerFunction;
return largeObject.data.length;
}
return innerFunction;
}
const counter = outerFunction();
// 即使不再使用counter,由于循环引用,largeObject和innerFunction都无法被垃圾回收
- 未释放的引用:如果闭包被长时间持有,而闭包中引用的变量不再需要,但因为闭包的存在不能被回收,就会导致内存泄漏。例如,将闭包作为全局变量存储,且一直未释放对该闭包的引用。
如何避免内存泄漏
- 解除循环引用:在适当的时候,手动解除循环引用。例如在上述例子中,在不再需要
innerFunction
时,将largeObject.referenceToInner
设置为null
。
function outerFunction() {
const largeObject = { data: new Array(1000000).fill(0) };
function innerFunction() {
largeObject.referenceToInner = innerFunction;
return largeObject.data.length;
}
return innerFunction;
}
const counter = outerFunction();
// 不再需要counter时
counter = null;
// 手动解除循环引用
if (largeObject && largeObject.referenceToInner) {
largeObject.referenceToInner = null;
}
- 及时释放引用:避免将闭包长时间作为全局变量持有。如果需要使用闭包,尽量在其完成使命后,及时释放对闭包的引用,以便垃圾回收机制能够回收相关内存。