• js---11闭包


     //匿名立即调用函数
    (function(){//把a,b,f全部隐藏在函数中,外部访问不到,
        var  a = 5;
        var b = 6;
        function f(){
            alert(a);
        }
        window.f  = f;//为了让外部能够访问,把变量a,b隐藏了防止了变量名冲突。保证内成函数使用的变量仅仅是外层函数包括的变量,防止了变量重名。
    })();
    f();
    //自己的scope属性 ==  父级的环境,
    //自己的scope属性 == 自己的环境
    //闭包:
    //函数的嵌套相当于类的继承,函数相当于类,外部函数的变量也是内部函数的,内部函数可以使用,并且变量可以重写(类似于方法的重写)
    //作用域链、闭包:函数的嵌套,不是外部类与内部类的关系,是父类与子类的关系,函数是类,内部函数是子类。
    //在js层面,只有函数嵌套才会产生闭包。(闭包和全局window对象在浏览器里面都可以查看)。
    //闭包的本质是因为js支持作用域链和函数的嵌套。要有函数嵌套才会产生闭包。(词法作用域==静态作用域==闭包)
    function f1(){
        var a = 10;
        var b = 20;
        function f2(){//运行在这里的时候就创建了f2的闭包,并且把a,b放在f2的闭包中,所以f2中可以访问a,b.
            console.log(a);//可以访问a,b
        }
        f2();
    }
    f1();
    
    function f1(){
        var a = 10;
        var b = 20;
        return function f2(){
            console.log(a);
        }
    }
    var r = f1();
    r();//可以访问a,b,由于f2函数(子类)可以访问外部函数(父类)的变量,所以f2函数(子类)运行的时候就会少传递参数(因为可以直接使用父类的成员,包括父级函数的形参)。
    
    
    
    function f1(){
        var m = 10;
        function f2(){
            console.log('a');//f2函数没有用到外部函数的变量,不会产生闭包。
        }
        f2();
    }
    f1();
    
    
    function f1(){
        var m = 10;
        function f2(){
            var n = 20;
            function f3(){
                console.log(m);//f3不用父级的成员,用父级的父级的成员,会产生闭包
            }
        }
        f2();
    }
    f1();
    
    
    ----------------------------------------------------------
    不用全局变量,使得调用一个函数多次可以使得一个变量累加。
    function add(){
        var  a= 0;
        return function(){
            a++;
            ALERT(a)
        };
    }
    var f = add();
    f();f();f();
    
    //使用闭包注意点:
    //捕获的父级的变量只是一个引用,不是复制
    function f(){//父类
        var num = 1;
        function g(){//子类
            alert(num);
        }
        num++;
        g();//子类对象执行
    }
    f();//2
    
    //
    分析闭包的时候,把函数通过小括号f()执行,不当成c++的函数通过地址调用,当成java的匿名对象执行,分析闭包作用域。
    父函数每执行一次产生不同的闭包,函数通过地址调用多次,会产生多个独立的作用域,类似于java多个对象产生 function f(){ var num = 1; return function(){//把子类对象return出去,每return一次都是一个新的对象 num++; alert(num); } } var r1 = f(); r1();//2 r1();//3 var r2 = f();//2个对象 r2();//2 r2();//3 <div id='1'></div> <div id='2'></div> <div id='3'></div> for(var i = 1;i<3;i++){//js没有块作用域,等价于var i ;声明在for的外面,i是一个全局变量, var d = document.getElementById(i); //这里的i已经使用了,所以i对应是0,1,2 d.onclick = function(){ alert(i);//每次都是4,可以通过this,这里i没有使用,一直是i,最后使用的时候i是4了, } } //改写,通过闭包(函数嵌套来解决) for(var i = 1;i<3;i++){ var d = document.getElementById(i); d.onclick = (function(id){ //匿名函数并且立即执行,这里i使用了所以是0,1,2, return function(){ //onclick = 3个不同的子类函数对象,3个子类对象的id值不一样 alert(id); } })(i); //i作为参数传递给id } </script>

        d.onclick函数每执行一次就会产生一个独立的闭包,互不影响,闭包类似于一个对象,互不影响。

    分析闭包的时候,把函数通过小括号f()执行,不当成c++的函数通过地址调用,当成java的匿名对象产生了,子函数就是子对象,分析闭包作用域。


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Untitled Document</title>
            <script type=text/javascript charset=utf-8>
            var name = "xiao A";
            var obj = {
                  name : "xiao B" ,
                  getName: function(){
                    return function(){
                        return this.name;
                    }
                }
            };
            var k = obj.getName();  //函数结构体return function(){returnthis.name;},这个函数返回后就是全局window的了。
            alert(typeof k); // function类型
            alert(k());//xiao A
            alert(obj.getName()());    //xiao A    ,obj.getName()执行后函数就是window的了,
            
            var name = "xiao A";
            var obj = {
                  name : "xiao B" ,
                  getName: function(){
                    // this总是指向调用者
                    var o = this;//this是调用getName的对象
                    return function(){
                        return o.name;//o是this,子对象的o永远是父对象的
                    }
                }
            };
            alert(obj.getName()());    
            var k = obj.getName();//xiao B
            alert(k());
            
            
            // 闭包:一个函数 可以访问另外一个函数作用域中的变量
            // 封闭性 : private 起到一个保护变量的作用
            // 1 
            function f(x){        // 2 
                var temp = x ;         //局部变量     //temp已经没有被使用    
                return function(x){        // 3 (function 有了一个执行域 var obj)
                    temp += x ;        //  又被使用了                        
                    alert(temp);                        
                 }
            }                
            var a = f(50); //父类只有一个
            alert(a);
            
            a(5);    //子对象1,55            
            a(10);//子对象2,65
            a(20);        //子对象3,85    
            </script>
        </head>
        <body>
        </body>
    </html>
  • 相关阅读:
    jquery 滚动条插件 jquery.nanoscroller.js
    Lost connection to MySQL server at 'reading initial communication packet' 错误解决
    ajax上传图片 jquery插件 jquery.form.js 的方法 ajaxSubmit; AjaxForm与AjaxSubmit的差异
    转:MVC3系列:~Html.BeginForm与Ajax.BeginForm
    转:MVC2表单验证失败后,直接返回View,已填写的内容就会清空,可以这样做;MVC2输出文本;MVC2输出PDF文件
    Java中的Dom4j
    Java插件之Jrebel
    Idea中的一些快捷键
    Java中的XML
    SQL Server 表值函数
  • 原文地址:https://www.cnblogs.com/yaowen/p/6842335.html
Copyright © 2020-2023  润新知