美文网首页
ES5之闭包

ES5之闭包

作者: 收纳哥斯拉 | 来源:发表于2019-10-07 11:29 被阅读0次

    1、什么是闭包?

    • 概念

    闭包记住了声明scope下的变量,在别的时间空间下,调用函数时 ,依然可以读取到这些变量。

    • 原理分析
    function outer(){
      let n = 1;
      function inner(){
        console.log(n);
      }
    
      return inner;
    }
    
    const fn = outer();
    fn();
    

    以上案例,提出来的问题是:outer执行结束之后,函数空间消亡了,innern为什么还有值?原理是什么?

    在我的理解里,闭包可以想象成一个胶囊(persistent lexical scope data \ back pack),包裹住了变量n粘在函数inner上,一起返回给了fn,在memory中开辟一个存储空间放置这个胶囊。如果代码中有fn在执行,它会一直访问这个胶囊里的n值。什么时候不再有fn了,什么时候这个胶囊脱落掉消亡。

    • 用途

    两个用途:不污染global的变量池变量值的暂存

    2、 let和var的区别,let的产生背景?const又怎么理解?

    • 区别

    这两个关键词的最关键的区别是scopevar是认定的scope不包含forif等这类函数块的,letforif等函数块认定为一个scope

    • let的目的

    有一些需要在函数块中记住变量属性的表达式,ES5需要加上花括号,这样子嵌套的层级会很多。ES6的时候就发明了let来简化代码。

    • const的用法

    const是根据不变性原则提出了的用法,禁止重新赋值,例如

    const a = 1;
    a += 1;//❌
    a = 2; //❌
    const array = [1,2,3]
    array = [2,3,4]//❌
    array.push(4)//✅
    

    stackoverflow上经常有关于const的困惑,为什么const 的array,object,function,可以更改它们的值,因为这些数据的类型是引用数据类型,你push更改的是指向地址的数组,而不是赋值的地址。

    • 代码意见
      综上所述,const不会给immutability贡献什么实质上的力量,而且经常会引起困惑,除了基本函数用const之外,最好不要用const来赋值引用数据类型。在global范围内的值用var,在scope领域里的值用let,这样层级就清晰了。

    3、 var的变量提升底层原理是什么?

    本质上是由JS编译过程导致的。

    • 代码的执行分为两个步骤
    1. 对声明进行编译——为varfunction分配地址内存。
    2. 执行——进行正常的赋值。

    例如var a = 2; 编译器先不会管a = 2这一赋值步骤。它最先要做的是把var a编译掉,而运算操作留在原地。声明在编译角度上被移动到了作用域的顶端。这就是提升的底层原理。

    • 拓展话题——TDZ暂时死区
      image
      aVar的值符合提升的原则。aLet就有点意思了,它抛出来的错误实际上就是暂时死区错误。简单来说,从声明到到let的运算步骤为止的这段时空被锁死,外界在此期间寻求访问,不被允许。

    4、 模块化思想

    • 为什么要使用模块化?

    模块化思想即最小暴露原则。隐藏掉别人不需要知道的代码细节,仅提供需要使用的API。保护代码的安全性和可维护性。

    • 如何模块化?

    书写一段模块的要点有二:1、要使用闭包原理。2、函数至少被调用执行过一次。

    方法一:工厂模式

    function module(){
       let text = "baz";
       
       let publicAPI = {
           baz: fuction (){
               console.log(text);
           }
       }
       
       return publicAPI;
    }
    
    var foo = module();
    foo.bar();
    

    方法二:单例模式(IIFE)

    var foo = (function module(){
        let text = "baz";
        let publicAPI = {
            baz: function(){
         console.log(text);
        }
        return pubilcAPI;
     }
    })();
    foo.bar();
    

    相关文章

      网友评论

          本文标题:ES5之闭包

          本文链接:https://www.haomeiwen.com/subject/pgfmpctx.html