作用域,闭包

参考链接:https://juejin.im/post/5ec74c6a518825430956ae65#heading-5

什么是作用域链?

  当执行代码访问内部变量时,会查找本地作用域,如果找到目标即返回,否则会去父级作用域继续查找,一直到全局作用域,这种嵌套机制叫作用域链

静态作用域(词法作用域)?

  函数定义的时候作用域就已经确定,和拿到哪里执行没关系

块级作用域?

  花括号{}内的就是块级作用域

作用域应用场景(模块化)?

  解决全局作用域污染 和 变量名冲突 的问题

  使用立即调用模式函数模式,封装性更好,代码更简洁,解决了模块名全局作用域问题

什么是闭包?

   能够访问其他函数内部变量的函数

    闭包是指有权访问另一个函数作用域的变量的函数。创建闭包的的常用方式,就是一个函数内部创建另一个函数。
    闭包主要涉及到js的几个其他的特性:作用域链,垃圾(内存)回收机制,函数嵌套,等等

闭包的作用?  

  1:读取函数内部的变量

  2:将变量的值始终保存在内存中

  3:参数和变量不会被垃圾回收机制回收

  当函数返回了一个闭包时,这个函数的作用域将一直在内存中保存,直到内存中保存的闭包不复存在

        一般来讲,当函数执行完毕之后,函数内部的局部活动对象就会被销毁,内存中仅保存全局作用域,即js的内存回收机制。

  创建一个立即调用的函数,既可以执行其中的代码,又不会在内存中留下对该函数的引用
        如果这个函数内部又嵌套了另一个函数,而这个函数是有可能在外部被调用到的.并且这个内部函数又使用了外部函数的某些变量的话.这种内存回收机制就会出现问题。如果在外部函数返回后,又直接调用了内部函数,那么内部函数就无法读取到他所需要的外部函数中变量的值了.所以js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包,这些变量将不会被内存回收器所回收,只有当内部的函数不可能被调用以后(例如被删除了,或者没有了指针),才会销毁这个闭包,而没有任何一个闭包引用的变量才会被下一次内存回收启动时所回收。

闭包应用场景?

  1,单列模式:保证了一个类只有一个实例,一般先判断实例是否存在,存在就直接返回,否则就创建了再返回

     单列模式好处:避免了重复实例化带来的内存开销 

  2、模拟私有属性,对象中的方法和属性均可以访问,这就会有安全隐患,内部属性开发者都可以随意更改,虽然语言不支持私有属性,但是可以使用闭包模拟

  3、柯里化,

闭包的好处?

  ①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突

  ②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)

  ③匿名自执行函数可以减少内存消耗

闭包坏处?

  ①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;

  ②其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

  ③创建闭包必须维护额外作用域,过度使用可能会占用大量内存

内存泄漏解决方案?

  1,使用严格模式,避免不经意的全局变量泄漏

  2、在销毁阶段记得解绑相关事件

  3、避免过度使用闭包

 

 

 

 

原文地址:https://www.cnblogs.com/xiaohaha668/p/10713102.html