zoukankan      html  css  js  c++  java
  • 前端总结(一)闭包

    一、对闭包的理解,以及哪些地方用过闭包,以及闭包的缺点。

    闭包(closure)是javascript的一大难点,也是它的特色。很多高级应用都要依靠闭包来实现。

    (1)变量作用域

    javascript的变量作用域只有两种:全局变量和局部变量。

    javascript语言的特别之处就在于:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。

    注意:在函数内部声明变量的时候,一定要使用var命令。否则,默认的会添加到全局对象的属性上去,即声明的是全局变量!

    (2)如何从外部读取函数内部的局部变量?

    但我们有时候需要获取到函数内部的局部变量。上面已经说过了,正常情况下,这是办不到的!只有通过变通的方法才能实现。

    那就是在函数内部,再定义一个函数。

    function f1(){
        var n=999;
        function f2(){
          alert(n); // 999
        }
    }

    在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。

    这就是Javascript语言特有的"链式作用域"结构(chain scope),

    子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

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

    (3)闭包的概念

    上面代码中的f2函数,就是闭包。

    理解1: 闭包就是能够读取其他函数内部变量的函数

    理解2:闭包就是有权访另一个函数作用域中变量的函数。

    由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。

    所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

    (4)闭包的特点

    函数嵌套函数; 
    函数内部可以引用函数外部的参数和变量; 
    函数变量和参数不会被垃圾回收机制回收;

    (5)闭包的优缺点

    优点 
    - 希望一个变量长期驻扎在内存中 
    - 避免全局变量的污染 
    - 私有成员的存在 

    缺点 
    - 常驻内存,增大内存使用量,使用不当回造成内存泄漏;

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

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

     (6)闭包的用途

    闭包一般的用途在,轮播、幻灯片,通过闭包记住点击的index。

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

    为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

    二、闭包

    闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。

    闭包的特性:1.函数内再嵌套函数2.内部函数可以引用外层的参数和变量3.参数和变量不会被垃圾回收机制回收//li节点的onclick事件都能正确的弹出当前被点击的li索引

    <ul id="testUL">
    <li> index = 0</li>
    <li> index = 1</li>
    <li> index = 2</li>
    <li> index = 3</li>
    </ul>
    <script type="text/javascript">
     var nodes = document.getElementsByTagName("li"); 
    for(i = 0;i<nodes.length;i+= 1){
    nodes[i].onclick = (function(i){ 
    return function() {
    console.log(i);
    } //不用闭包的话,值每次都是4 })(i);
    }
    </script>

    执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在
    使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源
    因为say667()的内部函数的执行需要依赖say667()中的变量
    这是对闭包作用的非常直白的描述 function say667() { // Local variable that ends up within closure
    var num = 666; var sayAlert = function() {
    alert(num);
    }
    num++; return sayAlert;
    } var sayAlert = say667();
    sayAlert()//执行结果应该弹出的667

    三、介绍一下闭包和闭包常用场景?

    • 使用闭包主要为了设计私有的方法和变量,闭包的有点事可以避免变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念。
    • 闭包有三个特性:
      • 函数嵌套函数
      • 函数内部可以引用外部的参数和变量
      • 参数和变量不会被垃圾回收机制回收
    • 闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包常见方式,就是在一个函数的内部创建另一个函数
      • 应用场景,设置私有变量的方法
      • 不适用场景:返回闭包的函数是个非常大的函数
      • 闭包的缺点就是常驻内存,会增大内存使用量,使用不当会造成内存泄漏

    四、为什么会出现闭包这种东西?解决了什么问题?

    受javascript链式作用域链的影响,父级变量中无法访问到子级的变量值

  • 相关阅读:
    vim 使用总结
    C语言中的条件编译
    getopt函数
    Linux 命令使用总结
    vim ctags cscope
    shell 定时处理
    shell 脚本中的标准输出
    ubuntu mail 命令发送邮件
    shell 编程中的特殊字符的处理
    system v 消息队列
  • 原文地址:https://www.cnblogs.com/Crazy-D/p/10417258.html
Copyright © 2011-2022 走看看