JS面对对象基础--原型链

词法环境[[environment]]–闭包

闭包定义

一些书籍中对于闭包的定义:

  • 闭包是指有权访问另一个函数作用域中的变量的函数—《JavaScript高级程序设计》
  • 闭包允许函数访问并操作函数外部的变量—《JavaScript忍者秘籍》
  • 闭包使得函数可以继续访问定义时的词法作用域—《你不知道的JavaScript》
  • 所有JavaScript函数都是闭包—《JavaScript权威指南》

MDN

  • 函数和对其周围状态(词法环境)的引用捆绑在一起构成闭包
  • 也就是说,闭包可以让你从内部函数访问外部函数作用域(作用域链)。
  • 在JavaScript中,每当函数被创建,就会在函数生成时生成闭包。

[[Environment]]

[[Environment]]:内见属性

  • 每个函数都有;
  • 存放词法环境的作用;
  • v8引擎中无法读写;

对比之前学过的另一个内见属性[[Prototype]]

  • 每个函数(构造函数)都有;
  • 存放对象原型的作用;
  • 可以使用__proto__读写;

[[Environment]]叫词法环境对象:

  • 整个脚本文件执行前会产生一个
  • 函数实例创建后会产生一个

[[Environment]]属性记录了:当前函数的词法环境对象==>外层函数的词法环境对象==>全局的词法环境对象;这样就形成了作用域链

举例说明:

function fn() {
  const a = 1;
  function fo() {
    console.log('hi')
  }
}
fn()
//此时fn函数的[[Environment]]属性包括:作用域链
//1.当前环境的记录
a:1
fo:()=>console.log('hi')
//2.对外部词法环境的引用(全局词法环境)

闭包的例子:函数与词法环境捆绑

function fn() {
    let a = 1;
    return function fo() {
        console.log(a++)
    }
}
let x = fn()
x();//1
x();//2

//下面两种情况相当于创建了两个实例,
//当前面的函数执行完之后里面的变量和函数就被垃圾回收掉,
//所以不影响后面函数的执行依然打印的是a=1
fn()()//1
fn()()//1

我们分析一下上面函数不考虑词法环境的情况下的执行调用栈:

fn()入栈;变量a入栈;fn()和a一起出栈;x()入栈;(此时出现问题了,x()在执行过程中需要找到a,但是a又没在执行栈中,并不符合我们要的预期)

此时就需要在函数与词法环境捆绑,形成闭包来实现这个问题:函数执行前就形成词法环境写入[[Environment]]属性中:此时fo函数内部词法环境是只有一个console.log函数,外层函数词法环境是a:1,全局词法环境为空。

函数中在执行过程中的内部变量,并不是同函数一样被加入到调用栈中,而是在函数执行前形成词法环境写入[[Environment]]属性中保存。只要有函数就会有闭包,只是v8中有垃圾回收机制,当一个函数执行后不被其他变量所引用,这个函数中的变量就不会被垃圾回收掉。但是当函数执行后有变量引用它时,就这个函数里面的变量就永远不会被垃圾回收掉,需要我们手动操作回收变量。

下面的例子中const a这个变量就是被存放在词法环境对象[[Environment]]中。(下图可以解释为什么要有闭包。)

在这里插入图片描述

在这里插入图片描述

理解垃圾回收问题:

js变量回收规则:

  • 在js中定义的全局变量是不会被销毁的,因为随时都可能会用到这个变量,所以不能被销毁。
  • 具体引用关系的不会被销毁。
    • 如果一个对象不被引用,那么这个对象就会被回收;
    • 如果两个对象互相引用,但是没有被第3个对象所引用,那么这两个互相引用的对象也会被回收。

通过下面两段代码进行对比分析:

function a(){
  var b= 10;
  return function(){
    b++;
    console.log(num);
  }
}
a()(); //11
a()(); //11

分析:
在函数a中返回了一个匿名函数,在这个匿名函数中我们num++了一下,然后在函数外面执行了这个匿名函数函数,现在num是11,然后又执行了一次这个函数,你们应该是12吧,为什么不是呢?

原因:
js为了让没有必要的变量保存在内存中,(我们写的任何变量都是需要内存空间的)在不需要这个变量的时候它就会被销毁。所以每次执行一遍 a()() 则变量b就会被销毁。下次再执行,就会重新声明变量b,所以两次输出都是11。

function a(){
    var b = 0;
    return function(){
        b ++;
        console.log(b);
    }
}
var d = a();
d();//1
d();//2

原因分析:

  • 函数a 被 变量d 引用,更准确的说是 函数a 里面的 匿名函数 被变量d所引用。
  • 因为变量d 保存的是函数a执行完成后的值,而函数a执行完,返回了那个匿名函数,所以变量d等于匿名函数。
    -匿名函数因为使用了 函数a 中的 变量b 并且还被 变量 d所引用,所以就形成了一个闭包。
  • 只要这个变量d不等于null的话,那么那个变量b会一直保存到变量d中不会被销毁。
  • 所以两次执行的结果不一样

垃圾回收问题

1.什么是js的垃圾回收机制?

答:javascript中垃圾收集机制是自动回收的,不用人工操作,这让我们更专注于编辑代码上。 回收垃圾机制是定时执行的,具有周期性。

2.什么时候会有垃圾?

答:在作用域中当整个作用域中的代码执行完后,作用域中的变量和方法都会没用,此时就是被当做垃圾了。比如局部作用域,一个函数执行完,里面的变量就可以被销毁,其占用内存被释放。

3.垃圾回收方式?

答:常用的是标记清除:这样操作:一个变量–>进入环境(被标记,有此标记为不能被清除)–>执行–>离开环境(被标记,这个标记告诉机制能被清除)–>回收机制一段周期后,变量被清除。

4.为什么还要管理内存?

答:分配给web浏览器的内存比桌面的应用的内存少,这是出于安全考虑,为了防止运行js的网页耗尽系统内存导致系统崩溃。所以,开发者发现一旦数据不再用时,就将其值设为null来释放其引用(解除引用),这做法适用于全局变量和全局对象属性。

参考资料:

js闭包变量回收问题

垃圾回收问题

需求响应动态冰蓄冷系统与需求响应策略的优化研究(Matlab代码实现)内容概要:本文围绕“需求响应动态冰蓄冷系统与需求响应策略的优化研究”展开,基于Matlab代码实现,重点探讨了冰蓄冷系统在电力需求响应背景下的动态建模与优化调度策略。研究结合实际电力负荷与电价信号,构建系统能耗模型,利用优化算法对冰蓄冷系统的运行策略进行求解,旨在降低用电成本、平衡电网负荷,并提升能源利用效率。文中还提及该研究为博士论文复现,涉及系统建模、优化算法应用与仿真验证等关键技术环节,配套提供了完整的Matlab代码资源。; 适合人群:具备一定电力系统、能源管理或优化算法基础,从事科研或工程应用的研究生、高校教师及企业研发人员,尤其适合开展需求响应、综合能源系统优化等相关课题研究的人员。; 使用场景及目标:①复现博士论文中的冰蓄冷系统需求响应优化模型;②学习Matlab在能源系统建模与优化中的具体实现方法;③掌握需求响应策略的设计思路与仿真验证流程,服务于科研项目、论文写作或实际工程方案设计。; 阅读建议:建议结合提供的Matlab代码逐模块分析,重点关注系统建模逻辑与优化算法的实现细节,按文档目录顺序系统学习,并尝试调整参数进行仿真对比,以深入理解同需求响应策略的效果差异。
综合能源系统零碳优化调度研究(Matlab代码实现)内容概要:本文围绕“综合能源系统零碳优化调度研究”,提供了基于Matlab代码实现的完整解决方案,重点探讨了在高比例可再生能源接入背景下,如何通过优化调度实现零碳排放目标。文中涉及多种先进优化算法(如改进遗传算法、粒子群优化、ADMM等)在综合能源系统中的应用,涵盖风光场景生成、储能配置、需求响应、微电网协同调度等多个关键技术环节,并结合具体案例(如压缩空气储能、光热电站、P2G技术等)进行建模与仿真分析,展示了从问题建模、算法设计到结果验证的全流程实现过程。; 适合人群:具备一定电力系统、能源系统或优化理论基础,熟悉Matlab/Simulink编程,从事新能源、智能电网、综合能源系统等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①开展综合能源系统低碳/零碳调度的科研建模与算法开发;②复现高水平期刊(如SCI/EI)论文中的优化模型与仿真结果;③学习如何将智能优化算法(如遗传算法、灰狼优化、ADMM等)应用于实际能源系统调度问题;④掌握Matlab在能源系统仿真与优化中的典型应用方法。; 阅读建议:建议结合文中提供的Matlab代码与网盘资源,边学习理论模型边动手调试程序,重点关注同优化算法在调度模型中的实现细节与参数设置,同时可扩展应用于自身研究课题中,提升科研效率与模型精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值