本文目录一览:
js闭包怎么写
var result=[];
function foo(){
var i= 0;
for (;i3;i=i+1){
result[i]=function(){
alert(i)
}
}
};
foo();
result[0](); // 3
result[1](); // 3
result[2](); // 3
这段代码中,程序员希望foo函数中的变量i被内部循环的函数使用,并且能分别获得他们的索引,而实际上,只能获得该变量最后保留的值,也就是说.闭包中所记录的自由变量,只是对这个变量的一个引用,而非变量的值,当这个变量被改变了,闭包里获取到的变量值,也会被改变.
解决的方法之一,是让内部函数在循环创建的时候立即执行,并且捕捉当前的索引值,然后记录在自己的一个本地变量里.然后利用返回函数的方法,重写内部函数,让下一次调用的时候,返回本地变量的值,改进后的代码:
var result=[];
function foo(){
var i= 0;
for (;i3;i=i+1){
result[i]=(function(j){
return function(){
alert(j);
};
})(i);
}
};
foo();
result[0](); // 0
result[1](); // 1
result[2](); // 2
北大青鸟java培训:js解析机制与闭包分析?
随着互联网的不断发展,程序员在学习JavaScript编程开发上也有了更多的了解,今天我们就简单分析一下关于JavaScript编程解析机制以及闭包的一些常见问题。
js解析机制:js代码解析之前会创建一个如下的词法环境对象(仓库):LexicalEnvironment{}在扫描js代码时会把:1、用声明的方式创建的函数的名字;2、用var定义的变量的名字存到这个词法环境中;3、同名的时候:函数声明会覆盖变量,下面的函数声明会覆盖上面的同名函数;4、函数的值为:对函数的一个引用;变量的值为undefined;5、如果用函数表达式的方式创建一个函数:varfn=function(){}这样词法环境中存的是一个变量名fn,并赋值为undefined;在调用函数的时候如果在函数上面调用就会出现和变量一样的情况报错undefined;这也是以两种不同方式创建函数的区别;闭包:定义:(有多种定义)1、(比较通俗的定义):函数嵌套函数,内部函数可以引用外部函数的参数和变量,这些参数和变量不会被垃圾回收机制所回收;2、在计算机科学中,闭包是词法闭包的简称,是引用了自由变量的函数,这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外(意思就是不会被销毁)。
3、闭包是由函数和其相关的引用环境组合而成的实体。
(潜台词就是这个函数将和引用环境同时存在,必须有引用)综合来说,不管怎么定义都是在围绕着两个本质:函数在引用变量,这个变量将不会被销毁。
闭包的一个作用就是:我们能够通过闭包的方法来在外部访问到一个内部函数的变量;很多人在解释闭包的时候都会把子函数return出去以后在外部调用,其实无论在哪里调用,闭包都已经形成了,只要是函数嵌套函数,并且子函数引用了父函数的变量,(不论子函数有没有被调用,电脑培训认为这个用一种方法证明:在子函数内部打断点,在f12中观察闭包里的内容,已经出现了引用函数,这时候调用还没有被执行)这个时候闭包已经形成了。
javascript中的window.ActiveXObject和闭包是什么意思有什么作用,在哪些情况下使用啊?
判断浏览器是否支持ActiveX控件
闭包的两个特点:
1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
例1。
scripttype="text/javascript"
functionsayHello2(name){
vartext='Hello'+name;//localvariable
varsayAlert=function(){alert(text);}
returnsayAlert;
}
varsy=sayHello2('never-online');
sy();
/script
作为一个Javascript程序员,应该明白上面的代码就是一个函数的引用。如果你还不明白或者不清楚的话,请先了解一些基本的知识,我这里不再叙述。
上面的代码为什么是一个闭包?
因为sayHello2函数里有一个内嵌匿名函数
sayAlert = function(){ alert(text); }
在Javascript里。如果你创建了一个内嵌函数(如上例),也就是创建了一个闭包。
在C或者其它的主流语言中,当一个函数返回后,所有的局部变量将不可访问,因为它们所在的栈已经被消毁。但在Javascript里,如果你声明了一个内嵌函数,局部变量将在函数返回后依然可访问。比如上例中的变量sy,就是引用内嵌函数中的匿名函数function(){ alert(text); },可以把上例改成这样:
scripttype="text/javascript"
functionsayHello2(name){
vartext='Hello'+name;//localvariable
varsayAlert=function(){alert(text);}
returnsayAlert;
}
varsy=sayHello2('never-online');
alert(sy.toString());
/script
这里也就与闭包的第二个特点相吻合。
例2。
scripttype="text/javascript"
functionsay667(){
//Localvariablethatendsupwithinclosure
varnum=666;
varsayAlert=function(){alert(num);}
num++;
returnsayAlert;
}
varsy=say667();
sy();
alert(sy.toString());
/script
上面的代码中,匿名变量function() { alert(num); }中的num,并不是被拷贝,而是继续引用外函数定义的局部变量——num中的值,直到外函数say667()返回。
例3。
scripttype="text/javascript"
functionsetupSomeGlobals(){
//Localvariablethatendsupwithinclosure
varnum=666;
//Storesomereferencestofunctionsasglobalvariables
gAlertNumber=function(){alert(num);}
gIncreaseNumber=function(){num++;}
gSetNumber=function(x){num=x;}
}
/script
buttononclick="setupSomeGlobals()"生成-setupSomeGlobals()/button
buttononclick="gAlertNumber()"输出值-gAlertNumber()/button
buttononclick="gIncreaseNumber()"增加-gIncreaseNumber()/button
buttononclick="gSetNumber(5)"赋值5-gSetNumber(5)/button
上例中,gAlertNumber, gIncreaseNumber, gSetNumber都是同一个闭包的引用,setupSomeGlobals(),因为他们声明都是通过同一个全局调用——setupSomeGlobals()。
你可以通过“生成”,“增加”,“赋值”,“输出值”这三个按扭来查看输出结果。如果你点击“生成”按钮,将创建一个新闭包。也就会重写gAlertNumber(), gIncreaseNumber(), gSetNumber(5)这三个函数。