javascript怎么通过闭包达到变量提升,迭代期以及其它的应用案例
var n;
function f1(pa){
var a = 'qwe' ;
n = function(){
return pa ;
};
pa++;
return n;
}
var q=f1(444);
console.log(q());
结果为:445
pa++;语句之前函数只是作了声明,并没有使用,在使用函数时,pa++已经执行了。
再来看一个例子
function f1(){
var n = 1 ;
text = function(){
n += 1 ;
}
function f2(){
console.log("f2中输出:"+n) ;
}
return f2 ;
}
var res = f1();
console.log("函数外输出:"+res()) ;
text();
console.log("函数外输出:"+res()) ;
这样层层传递,使f2编程全局变量的值,他就不会被垃圾回收机回收
var setValue,getValue;
(function(){
var n = 0 ;
getValue = function (){
return n ;
}
setValue = function (x){
n = x ;
}
})();
console.log("通过getValue得到的n:"+getValue());
setValue(567);
console.log("通过getValue得到的n:"+getValue());
console.log("直接得到的n:"+n);
可以看出,通过函数来实现值的调用和设置,这点就类似于java里面的面向对象的设计了,
而在函数外还是不可以直接获取n
通过闭包得到迭代器的效果
function test(x){
var i = 0 ;
return function (){
return x[i++];
}
}
var next = test(['q','w','e','r']);
console.log(next());
console.log(next());
console.log(next());
console.log(next());
循环中使用闭包
function f(){
var a=[];
var i;
for(i=0; i<3; i++){
a[i] = function(){
return i ;
}
}
return a ;
}
var test = f() ;
console.log(test[0]());
console.log(test[1]());
console.log(test[2]());
为什么会出现这种状况呢?
var声明的变量只有函数作用域,当调用f()后返回的i是最后一个i的引用
Javascript是一个单线程执行机制,for循环执行时函数并没有执行,函数执行时for循环已经结束,i已经变成了3,所以只会返回3
再来看看怎么解决这个问题
function f(){
var a=[];
var i;
for(i=0; i<3; i++){
a[i] = (function(x){
return function(){
return x ;
} ;
})(i);
}
return a ;
}
var test = f() ;
console.log(test[0]());
console.log(test[1]());
console.log(test[2]());
创建一个自调用函数,然后把每次调用的i传递给x,这样每次返回的值都不一样,
这样写可能难以理解,来看一个分解后的写法
function f(){
function text(x){
return function(){
return x ;
}
}
var a = [];
var i;
for(i=0; i<3; i++){
a[i]= text(i);
}
return a;
}
var res = f();
console.log(res[0]());
console.log(res[1]());
console.log(res[2]());
闭包时要注意:1.闭包会使得函数中的变量被保存在内存中,内存消耗很大,
2.闭包会在父函数外部,改变父函数内部的变量的值。