zoukankan      html  css  js  c++  java
  • 闭包

    闭包

    1.闭包的概念

    MDN中描述,闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。

    function init() {
        var name = "Mozilla"; // name 是一个被 init 创建的局部变量
        function displayName() { // displayName() 是内部函数,一个闭包
            alert(name); // 使用了父函数中声明的变量
        }
        displayName();
    }
    init();
    

    比如执行displayName(),diplayName的函数通过作用域链(

    了解js的执行过程:https://www.cnblogs.com/listenMao/p/13329620.html

    )得到name的值。通过 displayName()我们可以保存name的信息,这有赖于作用域链。js的词法作用域的特点是在函数创建定义时确定了作用域链,当一个内部函数(如displayName)变成一个闭包时,拥有 “他自身(如displayName)所形成的作用域链“。

    2.闭包的缺点

    function makeFunc() {
        var name = "Mozilla";
        function displayName() {//闭包
            alert(name);
        }
        return displayName;
    }
    
    var myFunc = makeFunc();//myFunc指displayName;
    myFunc();
    

    .通常,函数的作用域及其所有变量都会在函数(makeFunc)执行结束后被销毁。但是,在创建了一个闭包(displayName)以后,这个函数的作用域(makeFunc)就会一直保存到闭包不存在为止。存在占用内存。

    myFunc=null;//释放内存
    

    3.闭包的使用

    3.1模拟面向对象的方式

    使用闭包来定义公共函数,并令其可以访问私有函数和变量,实际上可以使用es6的类或者es5的构造函数

    var person=function(){
        //定义私有
        var name="";
        
        return {//暴露公共函数
            getName:function(){//
                return name;
            },
            setName:function(val){
                name=val;
            }
            
        }   
        
    }
    //建了一个词法环境,为2个函数共享。这2个公共函数是共享同一个环境的闭包。
    var p=person();p.setName(6);p.getName();
    

    3.2解决循环中类似输出i的错误

    //例子1
    //假设3个button,items为获取到的对应dom元素
    var items=document.getElementsByTagName("button");
    var len=items.length;
    for (var i = 0; i < len; i++) {
                items[i].onclick = function () {
                    console.log(i);//2,2,2
      }
    }
    
    //闭包解决
    //这一种是立即执行形成闭包
    for(var i = 0; i < len; i++) {
           (function(i){
            items[i].onclick = function () {
                    
                    console.log(i);//1,2,3
            }
            
            })(i);
               
    }
    //这一种是函数工厂,所有的回调不再共享同一个环境, make 函数为每一个回调创建一个新的词法环境
    var make=function(i){
        return function () {//这里不能是有参数i
                    
                    console.log(i);//1,2,3
       }
    }
    for(var i = 0; i < len; i++) {
        
            items[i].onclick =make(i);
            
               
    }
    //例子2
    for( var i=0;i<3;i++){
            setTimeout(function(){
                console.log(i); // 3,3,3
            }
            ,300);
      
    }
    
    
    
    //闭包解决
    for( var i=0;i<3;i++){
        (function(i){
            setTimeout(function(){
                console.log(i); // 1,2,3
            }
            ,300);
        })(i);
    }
    

    参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

  • 相关阅读:
    web.py利用模板的详细步骤
    Arduino入门笔记(9):蓝牙模块及第一辆蓝牙遥控小车
    Python常用模块之sys
    使用Supervisor管理Linux进程
    Python socket聊天室程序
    Ubuntu 文件文件夹查看权限和设置权限
    python遍历目录
    linux tail命令的使用方法详解
    Python使用openpyxl读写excel文件
    python中enumerate()的用法
  • 原文地址:https://www.cnblogs.com/listenMao/p/13369644.html
Copyright © 2011-2022 走看看