快速学会JavaScript中的闭包(3)

//循环中的闭包
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);

这个组件的作用是:初始化一个容器,然后可以给这个容器添加子容器,也可以移除一个容器。功能很简单,但这里涉及到了另外一个概念:立即执行函数。 简单了解一下就行。主要是要理解这种写法是怎么实现闭包功能的。

闭包并不是万能的,它也有它的缺点

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/50aabe8ab2e9b052f001118e8494f3da.html