JS底层运行原理:闭包机制

首先一起来看一道相关面试题:

let x = 1;
function A(y){
   let x = 2;
   function B(z){
       console.log(x+y+z);
   }
   return B;
}
let C = A(2);
C(3);

此道面试题的图解:
在这里插入图片描述
图解步骤分析:

  1. 所有代码执行都必须放在栈内存中执行,浏览器刚开始加载页面的时候会形成一个栈内存ECStack,也就是在内存空间里分配出一块空间来供代码执行。
  2. ECStack执行环境栈形成之后代码就可以执行来,首先全局的代码执行的时候要形成一个全局的执行上下文EC(G)
  3. 全局的执行上下文在形成之后要整体进栈执行,函数形成的私有的上下文也是要进栈(进入ECStack)执行的
  4. 所以以后的图解都不再画ECStack了,默认每一个形成的执行上下文肯定会进栈执行的。

GO和VO(G)本身不是一样的:
GO全局对象(浏览器中指window):是放在栈内存中的即堆内存,存放浏览器内置的API
VO(G)全局变量对象:是放在栈中的,即执行上下文中的空间,全局上下文中创建的变量
GO和VO(G)的关联:
基于var/function在全局上下文中声明的全局变量也会给GO赋值一份(两者存在映射机制,一个改变另一个也随之改变)
但是基于let/const等ES6方式在全局上下文中创建的全局变量和GO没有关系

//在控制台中输入
var a=10
a;//=>10
window.a;//=>10
window.a=12;//=>12
a;//=>12
a=13;//=>13
window.a;//=>13

let b=1;//=>undefined
window.b;//=>undefined
  1. 代码在执行之前都会进行变量提升:function A(y){……},提前声明+定义,函数是引用数据类型,所以会创建一个堆内存,这个堆内存是在全局上下文中创建的,所以一定会与全局上下文有一个关联,所有的堆内存都会有一个16进制都地址,比如0x00000。在函数这个堆内存里首先存储的是代码字符串(函数体中的代码),因为函数也是对象,所以这个堆中也存有健值对:name:A、length:1
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包在编程中有很多应用场景,以下是一些常见的例子: 1. 数据封装和私有变量:闭包可以用来创建私有变量,从而实现数据封装和保护。这在模块化编程和面向对象编程中非常有用。 2. 函数工厂:闭包可以用来创建一系列相关的函数,这些函数共享相同的外部变量。这在创建类似于Python中的装饰器或JavaScript中的高阶函数时非常有用。 3. 延迟执行和计时器:闭包可以用来实现延迟执行和定时器功能。例如,在JavaScript中,setTimeout和setInterval函数使用闭包来实现延迟执行和定时器功能。 4. 记忆化(Memoization):闭包可以用来实现记忆化,即缓存函数的计算结果,以便在后续调用中重用。这可以提高函数的性能,特别是在处理计算密集型任务时。 5. 事件处理和回调函数:在JavaScript等事件驱动的编程环境中,闭包常用于实现事件处理和回调函数。闭包可以捕获事件处理函数的上下文,使得事件处理函数可以访问其所需的外部变量。 6. 部分应用(Partial Application)和柯里化(Currying):闭包可以用来实现部分应用和柯里化,这是一种将多参数函数转换为一系列单参数函数的技术。这可以简化函数调用,使得代码更加简洁和可读。 7. 实现迭代器和生成器:在某些编程语言中,例如Python和JavaScript闭包可以用来实现迭代器和生成器,这是一种用于遍历数据结构的高效方法。
07-14

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值