//循环中的闭包
function fn(){
var a = [];
for(var i=0;i<3;i++){
a[i] = function(){
return i;
}
}
return a;
}
var a = fn();
console.log(a[0]());//3
console.log(a[1]());//3
console.log(a[2]());//3
/*
* 我们这里创建的三个闭包,结果都指向一个共同的局部变量i。
* 但是闭包并不会记录它们的值,它们所拥有的只是一个i的连接,因此只能返回i的当前值。
* 由于循环结束时i的值为3,所以这三个函数都指向了3这一个共同值。
* */
思考:如何使结果输出分别为0、1、2呢?
思路一:我们可以尝试使用自调用函数
function fn(){
var a = [];
for(var i=0;i<3;i++){
a[i] = (function(x){
return function(){
return x;
}
})(i);
}
return a;
}
var a = fn();
console.log(a[0]());//0
console.log(a[1]());//1
console.log(a[2]());//2
思路二:我们将i值本地化
function fa(){
function fb(x){
return function(){
return x;
}
}
var a = [];
for(var i=0;i<3;i++){
a[i] = fb(i)
}
return a;
}
console.log(a[0]());//0
console.log(a[1]());//1
console.log(a[2]());//2
------------------------------------------------------分界线-------------------------------------------------------
在这里,我们来对闭包进行更深一步的操作
我们再将demo1的例子进行扩展
代码示例如下:
function funcTest(){
var tmpNum=100; //私有变量
//在函数funcTest内
//定义另外的函数作为funcTest的方法函数
function innerFuncTest(
{
alert(tmpNum);
//引用外层函数funcTest的临时变量tmpNum
}
return innerFuncTest; //返回内部函数
}
//调用函数
var myFuncTest=funcTest();
myFuncTest();//弹出100
到样,我们对闭包的概念和用法有更加熟悉
闭包和this相关
闭包应用举例,模拟类的私有属性,利用闭包的性质,局部变量只有在sayAge方法中才可以访问,而name在外部也访问,从而实现了类的私有属性。
function User(){
this.name = "foodoir"; //共有属性
var age = 21; //私有属性
this.sayAge=function(){
console.log("my age is " + age);
}
}
var user = new User();
console.log(user.name); //"foodoir"
console.log(user.age); //"undefined"
user.sayAge(); //"my age is 21"
关于闭包更深入的了解
前面在demo6中,我们了解了用自调用方法来实现闭包,下面我们用这种方法来进行更复杂的操作(写一个简单的组件)。
(function(document){
var viewport;
var obj = {
init:function(id){
viewport = document.querySelector("#"+id);
},
addChild:function(child){
viewport.appendChild(child);
},
removeChild:function(child){
viewport.removeChild(child);
}
}
window.jView = obj;
})(document);
这个组件的作用是:初始化一个容器,然后可以给这个容器添加子容器,也可以移除一个容器。功能很简单,但这里涉及到了另外一个概念:立即执行函数。 简单了解一下就行。主要是要理解这种写法是怎么实现闭包功能的。
闭包并不是万能的,它也有它的缺点