• 作用域与闭包


    作用域

    作用域指程序中定义变量的区域,它决定了当前执行代码对变量的访问权限。

    全局作用域

    最外层的作用域,第一次执行代码的默认环境,一直存在,在全局作用域中的变量,可以被所有的函数访问。

    函数作用域

    在函数被定义时生成的作用域,函数作用域内的全部变量都可以在整个函数的范围内使用及复用,在这个函数作用域中嵌套的作用域也可以使用。

    作用域链

    当可执行代码内部访问变量时,会先查找本地作用域,如果找到目标变量即返回,否则会去父级作用域继续查找,一直找到全局作用域。我们把这种作用域的嵌套机制,称为作用域链。具体情形如下:

    1. function fun1(a) {
    2. var b = a+1;
    3. function fun2(c) {
    4. console.log( a, b, c );
    5. }
    6. fun2(b+1);
    7. }
    8. fun1(1); // 1 2 3

    不难看出,在函数fun2中,找不到变量a和变量b,因此它一层层作用域向上查找,最终找到了变量a,b。

    词法作用域

    词法作用域也就是在词法阶段定义的作用域,是由你在写代码时将变量和块作用域写在哪里来决定的,意味着函数的作用域在函数被定义的时候就已经确定了,和他在哪里执行没有关系。

    1. var value = 1;
    2. function fun() {
    3. console.log(value);
    4. }
    5. function fun2() {
    6. var value = 2;
    7. fun(); //函数是在这一行被定义的。
    8. }
    9. fun2();//输出的是2

    闭包

    官方说闭包就是指有权访问另一个函数作用域中的变量的函数。MDN 对于闭包的解释是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。我的理解是闭包就是函数内部定义的函数,被返回了出去并在外部调用。由于函数使用了外部作用域中的某些变量,因此当外部作用域释放时,这些变量因为要被闭包所使用,因此被保护了起来。

    1. function fun1() {
    2. var a = 1;
    3. function fun2() {
    4. console.log(a);
    5. }
    6. return fun2;
    7. }
    8. var a = fun1();
    9. a();

    闭包变量存储的位置

    闭包变量存储于堆内存之中。

    闭包的应用场景

    一般用于保护某些变量。也可用来模拟私有属性和柯里化函数。

    模拟私有属性

    1. function getPersonMessage () {
    2. var _name = '哈哈哈';
    3. var _sex = '男';
    4. var _age = 20;
    5. return function () {
    6. return {
    7. getName: function () {return _name;},
    8. getSex: function() {return _sex;},
    9. getAge: function() {return _age;},
    10. };
    11. };
    12. }
    13. var person = getPersonMessage()();
    14. person.getName(); // 哈哈哈
    15. person.getAge(); // 20
    16. person.getSex(); // 男
    17. person._name; // undefined

    闭包的缺陷

    内存溢出

    当程序运行所需的内存超出了剩余可分配的内存时,就会产生内存溢出,是一种程序运行出现的错误。                                                                                                                                             

    内存泄露

    什么是内存泄漏?

    js内部的垃圾回收机制是引用计数收集,即当内存中的一个变量被引用一次,计数就加一。垃圾回收机制会以固定的时间轮询这些变量,将计数为0的变量标记为失效变量并将之清除从而释放内存。但是在某些情况下,当一块内存不再被应用程序使用的时候,由于某种原因,这块内存没有返还给操作系统或者内存池,这种情况就叫做内存泄漏。内存泄漏可能会导致应用程序卡顿或者崩溃。

    引起内存泄露的情况有哪些:

    1. 意外的全局变量(写了var的是局部变量,没写var的是全局变量)
    2. 没有及时清理的计时器和回调函数
    3. 闭包                                            

    因此,闭包虽然好用,但是可以不用的时候尽量不要用,用了的话要及时清除。

  • 相关阅读:
    NFT价值体现在哪里 NFT有什么意义 怎么开发NFT平台
    Linux创建YUM仓库
    [Android Input系统学习]从mouse事件再看input分发
    算数平均法和加权平均法
    LLVM学习入门(2):实现解析器 Parser 和语法树 AST
    TCP/IP协议专栏——静态路由互导 详解——网络入门和工程维护必看
    一场直播帮你揭开保险代打卡背后的“猫腻”
    新日语(2)】第15課 張さんは部長に褒められました
    07_面向对象高级_内部类
    Seata入门系列【8】Seata之AT模式执行流程解析
  • 原文地址:https://blog.csdn.net/mhc20201554114/article/details/126842437