zoukankan      html  css  js  c++  java
  • javascript的作用域以及闭包现象

    1、 词法作用域

    词法作用域就是定义在词法阶段的作用域,换句话说,也就是js的作用域时在定义阶段决定的,和调用无关。

    1.1 作用域沿着作用链向上查找

    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
      //引擎执行console.log();在bar()内找不到a,向上查找,foo()也找不到,继续向上查找,在window全局中查找,找到a;
      function foo(){
          var b = a*2;
          function bar(c){
              console.log(a,b,c) // 2 4 8
          }
          bar(b*2);
      }
      var a =2;
      foo(2)

    </script>
    </html>

      

    1.2 函数作用域,定义函数时,会创建自己的气泡(作用域),外部作用无法直接访问。

    1.3 立即执行函数 IIFE(Immediately Invoked Function Expression)

    IIFE函数一般在前加上;防止()和前面的函数结合。


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
      var a = 100;
      (function foo(){
          var a =1;
          console.log(a);
      })()
      console.log(a); //100
    </script>
    </html>

    1.4块级作用域

    javascipt没有块级作用域,块级定义的变量会污染上一级作用域


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
          for(vart i=1; i<10; i++){}
          console.log(i); //10
    </script>
    </html>

    1.5 let语法

    es6引入let语法可以解决js没有块级作用域问题,强行绑定所在作用域


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
          for(let i=1; i<10; i++){}
          console.log(i); //报错
    </script>
    </html>

    let声明没有预解析,而且只能声明一次


    let flag = 123;
    let flag = 456; // 报错
    console.log(flag);

    console.log(num);  //报错
    let num = 123;

    1.6 变量提升

    先有蛋后有鸡(先声明后赋值)

    var a =1;分成var a 和a =2; 两步,第一步,定义声明是在编译阶段进行的,第二步赋值声明会被留在原地等待执行阶段。

    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
      console.log(a);
      var a =1;//undefined
      //第一步 var a ;第二步 console.log(a); 第三步 a =2;
    </script>
    </html>

    函数优先

    函数和变量的声明都会被提升,函数优先于变量


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
      foo(); //1
      var foo;
      function foo(){
          console.log(1);
      }
      foo = function(){
          console.log(2);
      }
    </script>
    </html>

    1.7 动态作用域

    js没有动态作用域,只有词法作用域


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
      function foo(){
          console.log(a) // 2
        // 如果有动态作用域,此处应该打印3

      }
      function bar(){
          var a =3;
          foo();
      }
      var a = 2;
      bar();

    </script>
    </html>

    小练习


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>
    </body>
    <script type="text/javascript">
      var b = 6;
      function test(){
          console.log(b); //undefined
          var b = 5;
          function a(){
              var b=1;
              console.log('a>>'+ b); //1
               
              function c(){
                  console.log('c>>'+b);// 1
              }
              c();

          }    
          a();
      }
      test();
    </script>
    </html>

    2、闭包

    函数在当前词法作用域之外执行,即产生了闭包。


    <!DOCTYPE html>
    <html>
    <head>
      <title></title>
    </head>
    <body>

    </body>
    <script type="text/javascript">
      function foo(){
          var a = 2;
          function bar(){
              console.log(a)
          }
          return bar;
      }
      var baz = foo();
      baz(); //2
    </script>
    </html>
  • 相关阅读:
    Django Rest framework FilterSet 设置 help_text
    树莓派:灯光,相机,动作,和非现场存储
    CFileDialogST v1.0
    使任何应用程序透明的Windows 2000/XP
    产生半透明的对话框和窗口没有闪烁
    一个酷的皮肤GUI与阴影边界
    使用图像蒙皮的表单
    一个控制皮肤组织的控制
    写一个潦草的应用程序使用可视化组件框架
    CRegionCreator
  • 原文地址:https://www.cnblogs.com/Jason-lin/p/9264993.html
Copyright © 2011-2022 走看看