zoukankan      html  css  js  c++  java
  • 词法作用域2

    1. 隐藏内部实现
      1. 最小授权原则 -- 最小限度地暴露必要内容。
      2. 所以不会将变量和函数都声明在全局作用域中
        1. function doSomething(a) {
              b = a + doSomethingElse(a * 2);
          
              console.log(b * 3);
          }
          
          function doSomethingElse(a) {
              return a - 1;
          }
          
          var b;
          
          doSomething(2);    // 15

          变量b和函数doSomethingElse()是函数doSomething()的私有内容,外部作用域可以访问到是危险的,下面将私有内容隐藏在函数内部。

        2. function doSomething(a) {
              var b;
          
              function doSomethingElse(a) {
                  return a - 1;
              }
          
              b = a + doSomethingElse(a * 2);
          
              console.log(b * 3);
          }
      3. 隐藏的作用
        1. 避免变量覆盖
          1. 第三方库中将需要暴露的功能加入命名空间
          2. 模块
    2. 函数作用域
      1. var c = 'hey';
        
        function bo() {
            var c = 'hi';
            console.log(c);
        
        }
        
        bo();    // hi
        console.log( c );    // hey

         上述代码的问题

        1. 函数bo()‘污染’了所在作用域,因为是一个具名函数

        2. 只能显式地通过函数名调用函数
      2. 期待能够不要函数的名字,并且没有名字也可以运行
        1. var c = 'hey';
          
          (function bo() {
              var c = 'hi';
              console.log(c);  // hi
          })();
          
          console.log(c);  // hey
        2. 区分函数和函数表达式就是看function关键字是否是声明的第一个词。
        3. 上面代码中,function前还有一个 '(' ,所以是函数表达式
        4. 所以 (function bo(){ .. }) 只能在 .. 中访问,不能被外部作用域访问。变量名bo被隐藏在自身中,最小授权
      3. 匿名和具名
        1. 匿名函数表达式的缺点
          1. 调试时,栈内并没有函数名
          2. 函数表达式递归时,只能用arguments.callee
          3. 可读性降低
        2. 行内函数表达式 -- 具名
        3. setTimeout( function() {
              console.log('等1秒!');
          }, 1000 );
          
          
          // 行内函数表达式
          setTimeout( function timeoutHandler() {
              console.log('等1秒!');
          }, 1000 );
      4. Immediately Invoked Function Expression --- 立即执行函数表达式
        1. var word = 'hi';
          
          (function IIFE() {
              var word = 'hey';
              console.log(word);    // hey
          })();
          
          console.log( word );    // hi

           函数IIFE中第一个括号将函数定义为函数表达式,第二个括号使函数立即运行

          下面是IIFE的另一种形式,将第二个括号写入第一个括号里
        2. var word = 'hi';
          
          ( function IIFE() {
              var word = 'hey';
              console.log(word);    // hey
          }() );
          
          console.log( word );    // hi
        3. 作用
          1. 匿名函数表达式
          2. 作为主调函数,传递参数
            1. var say = 'hi';
              
              (function IIFE(global){
                  var say = 'hey';
                  console.log(say);    // hey
                  console.log(global.say);    // hi
              }(window));
              
              console.log(say);    // hi
            2. 避免undefined的默认值被错误覆盖导致的异常(我还没见过)
              undefined = true;
              
              (function IIFE( undefined ) {
                  var a;
                  if (a === undefined) {
                      console.log('Undefined is safe here!');
                  }
              })();
            3. 倒置代码的运行顺序
              say = 'hi';
              
              (function run1(func) {
                  func(window);
              })( function run2(global) {
                  var say = 'hey';
                  console.log(say);    // hey
                  console.log(global.say);    // hi
              });

               函数run2在函数run1执行之后当作参数传进去

    3. 块作用域
      1. 为什么引入块作用域?
        var a = true;
        
        if (a) {
          var b = a * 2;
          console.log( b );   
        }

         尽管变量b声明在块作用域内,但是var声明的变量不具有块作用域的特性,所以变量b被绑定在全局作用域内,污染了全局作用域,破坏了最小暴露原则。

        • 块作用域可以将隐藏在函数内的信息扩展为块中隐藏的信息。所以能提高代码的可维护性。
      2. with的块作用域(不懂)
      3. try...catch中catch的作用域,没遇到过,先放着
  • 相关阅读:
    Webpack 学习2
    Webpack 学习
    JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后
    JS魔法堂:再识Number type
    基础野:细说浮点数
    基础野:细说有符号整数
    基础野:细说无符号整数
    基础野:细说原码、反码和补码
    Vim魔法堂:认识快捷键绑定
    Httpd运维日志:通过apxs添加模块
  • 原文地址:https://www.cnblogs.com/wydumn/p/11577865.html
Copyright © 2011-2022 走看看