美文网首页
javascript立即执行函数和闭包

javascript立即执行函数和闭包

作者: 啦啦啦_e26f | 来源:发表于2019-02-23 17:18 被阅读3次

    闭包

    概念:当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链
    举例分析:

    function  a(){
        function b(){
            var bbb = 234;
            console.log(aaa);
        }
        var aaa = 123;
        return b;
    }
    var glob = 100;
    var demo = a();
    demo();
    //a函数在执行的时候,会生成自己的执行期上下文AO对象,b函数是在
    //a函数内部定义的,所以b函数在定义的时候,形成的执行期上下文队像
    //就会有a函数的AO对象,当a函数执行完毕的时候,内部的变量会被当作垃圾
    //回收,此时a函数的执行期上下文被销毁,但a产生的AO对像并没有被当作垃圾回收,
    //因为此时b函数被保存出来,然后javascript程序并没有运行完毕,
    //b函数依然指向a函数的AO对象,b执行的时候依然可以从a函数内部拿值
    

    闭包的应用:

    //1,实现累加器
    function add(){
        var num = 100;
        function b (){
            num++;
            console.log(num);
        }
        return b;
    }
    var counter = add();
    counter();//101
    counter();//102
    //b函数每次都是拿的add函数所产生的那个AO对象,所以每次都会加一
    //2,可以做缓存
    function eater(){
        var food = "";
        var obj = {
            eat:function (){
                console.log('i am eating'+food);
                food = "";
            },
            push:function (myFood){
                food = myFood;
            }
        }
        return obj;
    }
    var eater1 = eater();
    eater1.push('banana');
    eate1r.eat();
    //3,私有化变量
    function Father(surname,address){
      var money = 10000;
      this.xing = surname;
      this.address = address;
      this.howmuchmony = function (){
        console.log("我有多少钱:",money);
      }
    }
    var son = new Father("sun","杭州");
    son.money;//访问不到
    son.howmuchmony();//只有son提供了相应的方法,你才能访问到
    

    立即执行函数

    概念:执行完立即被销毁的函数,javascript提供给我们的唯一可以执行完手动销毁函数的方式。
    实则是被当作表达式被括号执行了。此类函数没有声明,在一次执行过后即释放。适合做初始化工作。
    假设全局有两个函数a和b,这两个函数除非等到javascript执行完,不然一直占用内存空间得不到释放。
    形式1:( function () {}() );//w3c建议第一种
    形式2:( function () {})();
    其他的一些写法:

     function test(){
        var a = 123;
     }();
    //这种形式不能执行,这种叫函数声明,只有表达式才能被执行符号执行
    
    var test = function (){
        console.log(5464);
    }();
    + function test1(){
        console.log(8788);
    }();
    - function test2(){
        console.log(8788);
    }();
    ! function test3(){
        console.log(8788);
    }();
    (function test() {
        console.log(89);
    }());
    //+,-,!会把函数声明变成表达式,所以能被执行,能被执行符号执行的表达式会自动忽略函数名,
    //此时test(),是undefined,这种写就相当于立即执行函数,执行完被释放,test写了也没意义。
    

    下面看些题目

    一、
    function test4(a,b,c,d){
         console.log(a+b+c+d);
     }();//这样程序会报错
    function test4(a,b,c,d){
        console.log(a+b+c+d);
    }(1,2,3,4);
    //理论上不能执行,这样不会报错,也不会执行函数,程序可以照常运行
    //因为()如果当成执行符号就会报错,系统是能不报错就不报错,就会解释成
    // function test4(a,b,c,d){
    //     console.log(a+b+c+d);
    // }
    //  (1,2,3,4);这样的两段代码
    //把(1,2,3,4);解释成都好表达式
    //test()还是可以运行
    
    二、
    function test5(){
        var arr = [];
        for(var i=0;i<10;i++){
          ( function(j){
    
            arr[j] = function (){
                console.log(j);
            }
          }(i))//立即执行函数里面有函数被返回,也是可以访问里面的变量,闭包的应用
        }
        return arr;
    }
    var myArr = test5();
    for(var i=0;i<myArr.length;i++){
        myArr[i]();//每次去访问i的时候,都是去不同的AO对象里面去找
    }
    
    三、
    使用原生js,addEventListener,给每个li元素绑定一个click事件,输出他们的顺序
    <ul>
            <li>a</li>
            <li>a</li>
            <li>a</li>
            <li>a</li>
     </ul>
    function foo(){
        var liCollection = document.getElementsByTagName("li");
        for(var i=0;i<liCollection.length;i++){
            (function(j){
               liCollection[j].addEventListener("click",function(){
                console.log(j);
                })
            }(i))
            
        }
    }
    foo();
    
    四、
    写一个方法,求一个字符串的字节长度。(提示:字符串有一个方法charCodeAt();一个中文占两个字节,一个英文占一个字节)
    charCodeAt()方法可返回指定位置的字符串Unicode编码。这个返回值是0-65535
    之间的整数。当返回值是<=255时为英文,当返回值>255时为中文
    // function retBytesLen(str){
    //     var count = 0;
    //     for(var i=0;i<str.length;i++){
    //         if(str.charCodeAt(i)<=255){
    //             count++;
    //         }else{
    //             count+=2;
    //         }
    //     }
    //     return count;
    // }
    function retBytesLen(str){
        var len = str.length;
        var count = len;
        for(var i=0;i<len;i++){
            if(str.charCodeAt(i)>255){
                count++;
            }
        }
        return count;
    }
    
    五、
    var f = (
            function f(){
                return "1";
            },
            function g(){
                return 2;
            }
        )();
      console.log(typeof f)  //number
        // var f = (
        //     function g(){
        //         return 2;
        //     }
        // )();简化候就是立即执行函数
    
    六、
    var x = 1;
    if(function f(){}){
        x+=typeof f;
    }
    console.log(x);
    //括号会把函数变成表达式,变成表达式他就不是函数定义,就消失了
    //没定义的变量只有放在typeof 里面才不会报错,返回undefined,
    //typeof 返回字符串类型,
    七、
    
         function Person(name,age,sex){
            var a = 0;
            this.name = name;
            this.age = age;
            this.sex = sex;
            function sss(){
                a++;
                console.log(a); 
            }
            this.say = sss;
         }
         var person1 = new Person();
         person1.say();//1
         person1.say();//2
         var person2 = new Person();
         person2.say();//1
    
    

    相关文章

      网友评论

          本文标题:javascript立即执行函数和闭包

          本文链接:https://www.haomeiwen.com/subject/wrupyqtx.html