Javascript 在封闭函数返回后,**setInterval()调用的函数**如何访问封闭函数的变量?
我对Javascript的理解是,一旦函数完成了它的工作,该函数的局部变量就会被丢弃。但是,请考虑下面的代码:Javascript 在封闭函数返回后,**setInterval()调用的函数**如何访问封闭函数的变量?,javascript,scope,setinterval,Javascript,Scope,Setinterval,我对Javascript的理解是,一旦函数完成了它的工作,该函数的局部变量就会被丢弃。但是,请考虑下面的代码: document.onkeydown = function Encloser(evt){ evt = evt || window.event; switch(evt.keyCode){ case 88: var x = 50; var intrvl = setInterval(function Encloz
document.onkeydown = function Encloser(evt){
evt = evt || window.event;
switch(evt.keyCode){
case 88:
var x = 50;
var intrvl = setInterval(function Enclozee(){
console.log(x);
ctx.clearRect(0, 0, cnv.width, cnv.height);
actionRoutine(x--);
if(x < 0)
clearInterval(intrvl);
}, 50);
break;
}
// Redraw Routine
console.log(evt.keyCode);
ctx.clearRect(0, 0, cnv.width, cnv.height);
actionRoutine(50);
console.log("returning now");
};
document.onkeydown=函数封闭器(evt){
evt=evt | | window.event;
开关(evt.keyCode){
案例88:
var x=50;
var intrvl=setInterval(函数Enclozee(){
控制台日志(x);
ctx.clearRect(0,0,cnv.宽度,cnv.高度);
动作程序(x-);
if(x<0)
清除间隔(intrvl);
}, 50);
打破
}
//重画程序
console.log(evt.keyCode);
ctx.clearRect(0,0,cnv.宽度,cnv.高度);
行动程序(50);
console.log(“立即返回”);
};
每隔50ms调用一次的
Enclozee
,从内部访问变量x
和intrvl
,但这些操作在enclozer
返回后很久才会发生(通过在控制台上记录立即返回
)。怎么可能呢?封闭程序是否让垃圾收集器等待?这种行为不安全吗?在封闭程序
函数返回后,原语类型x
如何不从函数堆栈中删除?这个概念称为“闭包”。虽然有些语言在调用堆栈完成时会擦除所有局部变量,但javascript不是其中之一。只要存在从内存根到该变量的路由,变量就不会被垃圾收集
因此,只要有东西仍然引用该内部函数,内部函数使用的任何变量都不会被收集。在本例中,是setInterval的内部代码保留对内部函数的引用,它将继续这样做,直到调用clearInterval为止。在这一点之后,不再有对函数的引用,因此它可以与它引用的变量一起被垃圾收集。这个概念被称为“闭包”。虽然有些语言在调用堆栈完成时会擦除所有局部变量,但javascript不是其中之一。只要存在从内存根到该变量的路由,变量就不会被垃圾收集
因此,只要有东西仍然引用该内部函数,内部函数使用的任何变量都不会被收集。在本例中,是setInterval的内部代码保留对内部函数的引用,它将继续这样做,直到调用clearInterval为止。在这一点之后,就不再有对函数的引用了,因此它可以与它引用的变量一起被垃圾收集。这是安全的
这是因为当创建Enclozee
时,它也会创建一个闭包,允许它访问创建时在其范围内的所有变量,即使在其原始上下文结束后也是如此
您可以在此处阅读更多信息-它是安全的
这是因为当创建Enclozee
时,它也会创建一个闭包,允许它访问创建时在其范围内的所有变量,即使在其原始上下文结束后也是如此
您可以在这里了解更多信息-javascript实现中是否有函数堆栈,或者所有变量(包括原语)是否都进入堆?此外,如果堆栈存在,垃圾收集器是否也会处理堆栈的变量?这取决于浏览器或javascript引擎(我不确定是哪个引擎)来决定在何处分配变量。他们进行了优化,如果可能,将变量分配给堆栈,如果不可能,则分配给堆。作为一名开发人员,您需要知道的是,如果您编写引用变量的代码,它将对您可用(即,在堆上)。您从不使用的变量的情况取决于浏览器。javascript实现中是否有函数堆栈,或者所有变量(包括原语)是否都进入堆?此外,如果堆栈存在,垃圾收集器是否也会处理堆栈的变量?这取决于浏览器或javascript引擎(我不确定是哪个引擎)来决定在何处分配变量。他们进行了优化,如果可能,将变量分配给堆栈,如果不可能,则分配给堆。作为一名开发人员,您需要知道的是,如果您编写引用变量的代码,它将对您可用(即,在堆上)。您从未使用过的变量会发生什么情况取决于浏览器。