浏览器底层机制与函数底层机制

栈内存 EcStack (Execution Context Stack)

  • 浏览器会在计算机中的内存中分配一块内存,专门用来’供代码执行’的=> 栈内存 EcStack (Execution Context Stack) 执行环境栈
    • 供代码执行
    • 存储基本数据类型(变量/堆的引用地址)

全局对象 GO(Global Object)

  • 全局对象 GO)Global Object)是一个堆内存(存储的都是浏览器内置的API属性方法),在浏览器中会让window执行GO window指向GO (存放属性方法)
    浏览器把内置的一些属方法到一个单独的内存中 堆内存(heap)
    任何开辟的内存都有一个16进制的内存地址,方便后期找到这个内存

js中的执行上下文 EC(Execution Context)

  • EC(Execution Context)执行上下文:代码自己的执行所在的环境
    • 全局的执行上下文 EC(G)
    • 函数的代码都会在一个单独私有的执行上下文中处理
    • 块级的执行上下文

变量对象 VO(Varibale Object)

  • 变量对象:在当前的上下文中,用来存放创建的变量对象和值的的地方(每个执行上下文中都会有一个自己的变量对象,函数的私有上下文中叫做AO(Activation Object)活动对象,但是也是变量对象)
  • VO(G)全局变量对象:全局上下文中用来存储全局变量的空间,它不是GO=>只不过某些情况下VO(G)中的东西会和GO重的东西有所关联而已"映射机制"

活动对象 也是变量对象(私有) AO(Activation Object)

  • 函数进栈执行时形成一个全新的私有的上下文EC(FN(函数))供代码执行
  • AO是VO的一个分支,都是变量对象,AO是活动对象,函数中的变量对象都称为AO(FN(函数))私有变量对象

代码在执行的时候,形成的全局上下文,进入到栈内存中执行,简称‘进栈’,在执行完成代码后,可能会(没有被其他的上下文使用或占用)把形成的上下文出栈释放‘出栈’。栈的特点是先进后出

变量创建的方式

  • 创建一个值或对象(堆内存)
    • 基础数据类型值都是直接存储到栈内存的
    • 引用数据类型值是先开辟一个堆内存,把键值对存储在堆内存中,最后把地址放到栈中的提供的变量关联使用的
    • 所有的赋值操作都是指针的关联指向
  • 创建一个变量
  • 让变量和值关联在一起

函数

  • 函数也是一个堆,函数体中的代码当作字符串存储到堆中‘代码字符串’,函数不执行,函数没啥用
  • 函数也是对象,他有自己的键值对 name lenght(形参个数) prototype proto
  • 创建函数的时候,就定义了函数的作用域 => 当前创建的函数所在的上下文(当前函数的作用域)[[scope]]:EC(当前函数作用域)(默认EC(G))
  • 函数执行的目的? 让之前存储在堆中的代码字符串执行=>代码执行就要有自己的执行环境
    • 形成一个全新的私有的上下文EC(FN(函数))供代码执行(进栈执行)
      • 把全局上下文放到栈的底部(压缩栈)
      • 新进来的上下文放到栈的顶部(置顶)
        • 创建私有变量对象(AO(FN(函数名))
        • 初始化作用域链(scoppeChain):<EC(FN(函数名))自己所在的上下文,EC(G)创建函数时的作用域(上级上下文)>
        • 初始化this指向
        • 初始化实参集合:arguments
        • 形参赋值:在当前上下文中声明一个变量,把传递的实参赋值给它
          • 函数的形参也是存放在自己的上下文中的私有变量对象中
        • 变量提升
        • 代码执行
          • 把之前创建函数,在堆内存中存储的‘代码字符串’拿出来,变成一行行代码的执行
          • 代码执行时声明的变量也是私有变量
          • 在私有上下文代码执行的时候,遇到一个变量,我们首先看是否为自己的私有变量(在自己的变量对象EC(FN(函数名))中没有),如果是私有的(变量提升),则操作都是自己的,不是私有的,按照作用域链找上级上下文中的… 一直找到全局上下文为止。这就是作用域链查找机制
        • 上下文中的代码执行完毕,如果没有被占用或者被上级作用域使用,就会出栈释放

引用相同的堆内存地址(对象),如果一方改了对象里面的值,因为是地址,关联的都是同一个堆相互影响

var obj = {
    name:'哩哩啦啦'
    fn: (function (x){
        return x+10
    })(obj.name)
}
 
 console.log(obj.fn) // 直接报错 在语法分析.预编译阶段就报错了,先创建值,在创建变量去关联,所以在fn的值自执行时,obj是没有声明的(undefined.name),所以报错
执行环境栈
  • js之所以能够在浏览器中运行,是因为浏览器给js提供了一个执行环境=> 栈内存(Stack)
  • js中存在多种作用域(全局、函数私有的、块级私有的)代码执行之前,首先会形成自己的执行上下文、然后把上下文进栈(全局上下文压缩到栈的底部,新的上下文在顶部)、进栈后、在当前上下文中再依次执行代码
    • 全局执行上下文( EC(G) )
    • 私有上下文 ( EC(NAME) )
  • 作用域和执行上下文的关系,可以理解为:执行上下文是对应作用域中的代码执行环境
  • 每一个执行上下文中一定有一个空间用存储创建的变量对象
  • 一个页面只有一个VO(G)

    function fn(){}
    // 类似于
    var fn = function(){} // 函数表达式 把一个函数作为值赋值给一个变量或者其它的事物


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值