zoukankan      html  css  js  c++  java
  • 作用域&&闭包

    在了解闭包之前,先了解作用域
    一,作用域
    简单来说就是变量和函数可以访问的范围,在es5中变量作用域一般分为全局作用域和局部作用域,这个主要依据是全局变量还是局部变量

    情景1:
    <script>
      var global = 'global'
      function test () {
        var local = 'local'
          console.log(global)
        }
      test() // 返回global
      console.log (local) // 报错:Uncaught ReferenceError
    </script>
    此处的global就是全局变量,在整个代码内都可以访问到这个变量;变量local就是局部变量,只在函数local内部能访问到,在外部无法访问
    情景2:
    <script>
      var global = 'global'
      function test () {
        local = 'local'
      }
      test()
      console.log(local) // 返回 local
    </script>
    此处的global和local都是全局变量,在整个代码内都可以访问到这两个变量

    情景1和情景2的对比分析:
    因为JavaScript作为一门弱类型语言,声明一个变量只需要var一个保留字,如果在函数中不使用var声明变量,该变量将提升为全局变量,这就是为什么情景2中返回的值是local
    二,作用域链
    JavaScript里面采用的是函数作用域,每一个函数都有一个作用域,也算是一条独立的作用域链。比较典型的就是函数里面嵌套函数

    <script>
      var result = 'global'
      function test () {
        var result = 'local'
        function inner () {
          console.log(result) // 返回local
        }
        inner()
      }
      test ()
      console.log(result) // 返回global
    </script>

    以上三段作用域构成作用域链,作用域链的查找顺序:inner本函数-->上一层test函数-->window全局对象,当调用内部的inner方法的时候,里面没有声明变量result,但是可以访问外部函数test的变量,如果外部函数依然没有这个变量,就继续查找全局变量,直到找不到为止,如果找不到的话,就抛出 ReferenceError 错误。通过作用域链,子函数可以访问父函数的变量,但是父函数无法访问子函数里面的变量,闭包就可以解决这个问题。
    三,闭包
    简单的理解就是有权访问另一个函数作用域中的变量的函数。

    闭包理解的误区:
    <script>
      function test() {
        var result = 'local'
        return result
      }
      var res = test()
      console.log(res)
    </script>

    上面的这个是闭包函数么?答案显示是no!以上的函数确实是实现了外部可以访问函数内部的变量result,但是当函数调用完成之后,里面的变量result也就用完了被销毁了,即函数内的局部变量的生命周期仅存在于函数的声明周期内,函数被销毁,函数内的变量也自动被销毁,所以这个函数不是闭包函数

    闭包函数的正解,如下:
    <script> function test () { var result = 'local' function inner () { return result } return inner } var res = test() console.log(res()) // 返回local </script>

    上面的这段代码不仅实现了外部可以访问函数test内的变量result,同时当函数调用完的时候,通过闭包引用的外层作用域内的变量依然存在,并且将一直存在,直到执行的闭包作用域被销毁
    四,闭包的特点
    1,可以读取函数内部的局部变量
    2,局部变量的值可以存在内存中,可以反复使用,并且不存在全局变量的污染问题
    3,占用更多的内存,不容易被释放

    应用场景如下:
    <script>
      function count() {
        var num = 0
        function inner () {
          return num+=1
        }
        return inner
      }
      var result = count()
      console.log(result()) // 返回1
    </script> 
  • 相关阅读:
    四、创建多线程、数据共享
    operator函数操作符
    三、线程传参
    二、线程创建、结束
    一、并发、进程、线程概念
    bagging和boosting的区别
    ID3,C4.5和CART三种决策树的区别
    7创建型模式之建造者模式
    6创建型模式之工厂模式与抽象工厂模式
    5创建型模式之简单工厂模式
  • 原文地址:https://www.cnblogs.com/cn-andy/p/8575461.html
Copyright © 2011-2022 走看看