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);

此道面试题的图解:
JS底层运行原理:闭包机制_第1张图片
图解步骤分析:

  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

你可能感兴趣的:(javascript)