zoukankan      html  css  js  c++  java
  • javascript 闭包详解

    一、什么是匿名函数

    创建一个函数并将它赋值给变量functionName,这种情况下创建的函数,即匿名函数。(函数表达式就是匿名函数)

    二、闭包

    1.什么是闭包?

    闭包就是能够读取其他函数内部变量的函数。

    只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

    我们只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

    function f1 () {
        var num = 1;
        function f2() {
            console.log(num)
        }
        return f2;
    }
    var result = f1();
    console.log(result());  //1
    
    

    2、闭包的用途

    闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    function f1 () {
        var num = 1;
        function f2() {
            console.log(++num)
        }
        return f2;
    }
    var result = f1();
    console.log(result());  //2
    console.log(result());  //3

    原因就在于f1是f2的父函数,而f2的作用域绑上了f1函数的活动对象和全局变量对象(全家对象只有在网页关闭时才会销毁),这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制回收。

    3.使用闭包的注意点

    1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

     var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          return function(){
                    return this.name;   
         };   
        }
    };
    alert(object.getNameFunc()());  //The Window  匿名函数的执行环境具有全局性,因此其this对象通常指向window。

    4.闭包的应用场景

    1.使用闭包代替全局变量

    //全局变量,test1是全局变量
    var test1=111;
    function outer(){
        console.log(test1);
    }
    outer(); //111
    console.log(test1); //111
    
    //闭包,test2是局部变量,这是闭包的目的
    //我们经常在小范围使用全局变量,这个时候就可以使用闭包来代替。
    (function(){
        var test2=222;
        function test(){
            console.log("测试闭包:"+test2);
        }
        test(); //测试闭包:222
    }
    )();
    console.log(test2); //未定义,这里就访问不到test2 

    再如:
    (function(){
        var now = new Date();
        if(now.getMonth() == 0 && now.getDate() == 1){
            console.log("Happy new year!")
        }
    })();

    2.函数外或在其他函数中访问某一函数内部的参数

    function test () {
        var num = 1;
        function other() {
            console.log(++num)
        }
        return other;
    }
    var result = test();
    console.log(result());  //2
    console.log(result());  //3

      

    3.利用闭包模仿块级作用域

    (function(){
        for(var i =0;i<5;i++){
            console.log(i)
        }
        console.log(i); //5  //本身只是到4,但这个地方还是访问到了,所有输出了5
    })();
    console.log(i); //undefined  //利用闭包后,便形成了块级作用域,让外面访问不到了。
  • 相关阅读:
    (11)选择排序之二 树形选择排序
    (13)归并排序之一 2路归并排序递归形式
    (15)内部排序C++源码
    (10)选择排序之一 简单选择排序
    (14)归并排序之二 2路归并排序非递归形式
    (12)选择排序之三 堆排序
    Linux常用命令日常积累
    构建工具更新记录
    用javascript读取xml,并进行修改xml数据,解决保存没有权限问题
    免费的午餐(编程利用GoogleAPI发短信)移动联通都支持
  • 原文地址:https://www.cnblogs.com/chaixiaozhi/p/6719524.html
Copyright © 2011-2022 走看看