JavaScript中的作用域和闭包文档

作用域与闭包

1.环境

在计算机中,环境就是一块内存区域

执行环境:当函数被调用时会产生一个执行环境(内存地址),在执行环境中可以定义数据变量/函数等

执行环境有两个特点:

  • 有自身作用域,也就是作用范围
    • 全局作用域
    • 局部作用域
    • 块级作用域:在一个代码块(由一对花括号包裹)内部
  • 当环境不再被使用时,可以自动销毁或人为销毁

在js中,全局环境不会被回收,除非关闭页面或浏览器人为回收

2.环境的生命周期

function hd(){
    let n = 1;
    function sum() {
      console.log(++n);
    }
    sum();
}
hd();
hd();

有上述代码段,当执行hd()函数时,计算机内存表示为:全局环境->hd()环境->sum()环境

当执行多次hd()函数时,控制台会打印出两个2,而不是2,3

原因在于:每一次函数调用都会产生新的执行环境,而函数调用完成后就会销毁该执行环境(不用就会被清除)

解决办法:使用闭包

3.环境栈

在这里插入图片描述

全局执行环境是最外围的执行环境,被认为是window对象

当调用一个函数时,会产生一个执行环境并被压入环境栈中,js为每一个执行环境关联了一个变量对象,环境中定义的所有变量函数都保存在这个对象中

而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象

3.链式作用域

链式作用域(chain scope): 父对象的所有变量,对子对象都是可见的,反之则不成立;子对象会一级一级地向上寻找所有父对象的变量

当函数被调用时,会产生一个执行环境,并且每个执行环境会关联一个变量对象(变量对象中保存this,arguments对象),还会创建一个作用域链

链式作用域会指向父级的变量对象和自己的变量对象,当前执行环境的变量对象始终在作用域链的第0位

在这里插入图片描述

4.闭包

闭包就是能够读取其他函数内部变量的函数(该函数一定是一个内嵌函数)或对象

  • 从外部读取函数内部的变量
  • 试重保持变量在内存中,不被垃圾回收机制回收
function hd(){
    let n = 1;
    return function() {
      console.log(++n);
    }
}
let a = hd();
a();  //2
a();  //3
a();  //4

在上述代码中,外部变量a保持对function的引用(function属于引用型变量)

当function继续被引用时,其整个执行环境是会被继续保留在内存中的,所以变量n也是继续保存在内存中,达到封装变量的作用

使用闭包的注意点:

  1. 不能滥用闭包,会导致网页性能问题,也会导致内存泄漏

    解决办法:手动赋值为null/少用闭包

  2. 可能导致非预期的操作

  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      return function(){
        return this.name;
      };

    }

  };
    // The Window
    /*
    object.getNameFunc()会得到一个函数
    而该函数会在window执行环境中执行
    但是this并没有存储在内存中,所以this指向当前调用该函数的对象,即window
    */
  alert(object.getNameFunc()());
  var name = "The Window";

  var object = {
    name : "My Object",

    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };

    }

  };
    // My Object
    /*
    object.getNameFunc()得到返回的函数
    并且该函数是一个闭包
    可以对外部的that保持读取,而that为object对象
    */
  alert(object.getNameFunc()());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值