• 匿名函数和闭包(上)


    http://edu.51cto.com/lesson/id-6389.html

    匿名函数:没有名字的函数。

    闭包:

    闭包是建立在一个匿名函数里面的。

    闭包是指 有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式, 是在一个函数内部创建另一个函数,建议非必要时, 不要使用闭包,匿名函数也是差不多。

    即,闭包是一个函数,是能够访问别的函数作用域变量的函数,那么内部函数肯定能访问外部函数的变量,但是外部函数不能访问内部函数的变量(外部函数不能访问局部变量) ,若想实现这种访问,此时就用到了匿名函数 ( 闭包 )。所以闭包和匿名函数是什么关系呢?是包含关系,即闭包肯定是个匿名函数。

    一、匿名函数

    1.普通函数

    function box(){

    return 'lee';

    }

    alert(box()); //输出 lee

    2.匿名函数

    function (){

    return 'lee';

    }  //单独的匿名函数,无法运行。就算能运行,也无法调用,因为没有名称

    3.把匿名函数赋值给变量

    var box = function (){

    return 'lee';

    };

    alert(box()); //输出 lee

    alert(box);//输出function (){ return 'lee'; } 

    4.通过表达式自我执行  通过自我执行来执行匿名函数

    (匿名函数)(); 第一个圆括号放匿名函数,第二个圆括号执行

    (function (){

    alert( 'lee');

    })();  //输出 lee

    5.不用alert 用返回执行

    var box = (function(){

    return 'lee';

    })();

    alert(box);  //输出 lee  把匿名函数自我执行的返回值赋值给变量  区别与3.把匿名函数赋值给变量

    6.自我执行后 用alert打印 

    alert((function(){

    return 'lee';

    })());//输出 lee

    7.自我执行匿名函数的传参

    (function(age){

    alert(age);

    })(100);//在100的位置传参

    二、闭包

    1.函数里放一个匿名函数

    function box(){

    return function(){  //闭包 函数里的函数

      return 'lee';

    }

    }

    alert(box);

    //输出 

    function box(){

    return function(){

      return 'lee';

    }

    }

    alert(box());

    //输出 

     function(){

      return 'lee';

    }

    alert(box()());

    //输出 lee

    2.上述函数的另一种调用

    var b = box();

    alert(b()); //输出lee

    以上1 2 为铺垫,以下正式进入闭包

    闭包:是指有权访问另一个函数(如b函数)作用域中的变量的函数(如a函数),创建闭包的常见的方式就是在一个函数(b)内部创建另一个函数(a),通过另一个函数(a)访问这个函数(b)的局部变量。简单来讲,在b函数里创建a函数,a就是闭包,我们可以通过a函数来访问b函数的局部变量。

    3.通过闭包可以返回局部变量

    function box(){

    var age = 100;

    }

    alert(age);// 报错:age is not defined  因为age是私有的局部变量  外面访问不到  若在函数里面加上 return age;外部可以访问,但是这和闭包没有关系。

    以下为正确的 通过闭包返回局部变量

    function box(){

    var age = 100;

    return function(){

      return age;

    };

    }

    alert(box()());//输出100

    4.经典的例子  累加

    使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,命名冲突,每个模块都可调用必将引来灾难,所以推荐使用私有的,封装的局部变量)。

    普通函数的局部变量,调用的时候会存在内存中一会儿,调用完毕,则从内存自动销毁。若使用闭包,可以把局部变量驻留在内存中。

    //使用全局变量进行累加

    var age = 100;

    function box(){

    age++;

    }

    alert(age); //输出100

    box();

    alert(age);//输出101

    box();

    alert(age);//输出102  以上实现累加

    //使用局部变量进行累加

    function box(){

    var age=100;

    age++;

    return age;

    }

    alert(box());//输出101

    alert(box());//输出101  因为每次调用box(),都会初始化age=100

    //使用匿名函数实现局部变量驻留内存中从而累加  (真正要讲的是这个)

    function box(){

    var age=100;

    return function(){

    age++;

    return age;

    }

    }

    var b = box();

    alert(b());//输出101

    alert(b());//输出102

    alert(b());//输出103

    如果按照下面的调用,则不能实现累加

    alert(box()());//输出101

    alert(box()());//输出101  这样调用还是会初始化的。

    这里访问不到局部变量age

    alert(age);// not defined

    PS:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存,过度使用闭包会导致性能下降,建议在非常必要的时候才使用闭包。

    function box(){

    var age=100;

    return function(){

    age++;

    return age;

    }

    }

    var b = box();

    alert(b());//输出101

    alert(b());//输出102

    alert(b());//输出103

    alert(b);//输出函数,b会一直驻留在内存中,打印b,它就是 function(){age++; return age;}

    b = null; //最后不用了,解除引用,等待垃圾回收

    alert(b);//b is not a function

  • 相关阅读:
    Office365激活(无需密钥,无需下载软件)
    java垃圾回收及其优化
    Kafka副本机制
    sdn的相关学习系列之一mininet的安装
    javascript day 02
    关于javaScript
    html-day06
    盒子模型
    html-day04
    html--笔记day03
  • 原文地址:https://www.cnblogs.com/mabelstyle/p/3716212.html
Copyright © 2020-2023  润新知