前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS底层运行机制

JS底层运行机制

作者头像
子夜星辰
发布2022-11-15 16:20:52
1.9K0
发布2022-11-15 16:20:52
举报
文章被收录于专栏:李白偷偷偷猪

想要了解JS底层运行机制,首先要明白这几个概念:

为什么js能在浏览器中执行

众所周知,计算机是有内存的,计算机会在内存中开辟一块空间去供js执行,这个空间我们称之为执行栈

全局对象和全局变量对象是一样的吗

全局对象(Global Object),即window对象,存储着浏览器提供的内置方法,setTimeout,setInterval....

全局变量对象,在script标签内的代码执行时,会形成EC(G)的栈,EC(G)进栈(执行环境栈,EC Stack)执行,形成全局执行上下文(VO(G)),供给下级作用域

js中上下文有哪些

全局上下文(全局代码执行形成),记录为VO

私有上下文(函数执行形成),记录为AO

块级私有上下文

....

执行上下文

为了进行区域划分,会形成不同的执行上下文,全局环境会形成全局执行上下文,函数执行会形成函数执行上下文,通过作用域链scope chain形成链式关系

举个例子,var a = 12在底层是如何执行的

这里需要对栈内存和堆内存有个基本的了解

引用类型的值是存放在堆内存当中的

基本数据类型,也就是值类型,这种值是存放于栈内存当中

对于var a = 12,在计算机底层是先看等号右边的值,是引用类型还是值类型

需要了解一点,看似简单的赋值操作,实际上都可以归为三步操作

1.创建值

      创建值的过程,又可以细分,需要看值是什么类型

      如果是引用类型的话,那么就开辟一块堆内存,用来存放引用类型的值

      如果是值类型,那么就在栈内存中直接存放该值

2.声明变量,declare

3.将变量和值关联起来 defined

      这里的关联实际上,对计算机有所了解的,都会知道,这里是通过指针指向的行为进行关联

对于函数声明function fn(){}

底层会形成类似于fn = function (){},因为函数也是引用类型,故先创建堆内存,用来存放函数体内容,存放格式是字符串的形式

      再次说明下对象值类型,以此对比,对象类型,也是创建堆内存,存放形式时键值对的形式

      而对于数组值类型,也是创建堆内存,存放形式是,举个例子var arr = [1, 2] 存放形式(0 1, 1:2, length: 2)

函数在声明的时候,会生成其作用域[[scope]]指向当前函数声明所在的环境,如在全局中声明函数fn,则fn的作用域[[scope]]是EC(G),即指向全局执行上下文

对于函数执行fn()

1.形成私有化上下文,EC(fn)(包含了AO(fn)私有化变量对象,存放当前上下文中声明的变量),然后进栈执行,此时全局AO(G)压入栈底

2.代码执行之前,会进行预编译环节

      初始化作用域链 scope chain

      初始化this

      初始化arguments

      形参赋值

      变量提升

3.函数体代码执行

4.出栈释放


JS底层运行机制(成哥版,腾讯课堂有免费公开课

  • 函数都是对象,对象身上就会有属性,有的属性可以访问,有的属性不能直接访问
  • 函数执行多次会生成多个上下文,每个执行上下文都是独一无二的,函数执行完,执行上下文被销毁(只是指向被销毁,具体的执行上下文会定期被垃圾机制回收)
  • 函数定义的时候,会生成[[scope]]属性,用来存放当前函数的作用域,[[scope]]属性里面存在scope chain作用域链
  • scope chain作用域链,是存放执行上下文的集合的链表结构,在函数定义时,就会把当前函数所在的环境作为scope chain的第0位
  • scope chain[0] --> GO
  • 函数执行的时候,会生成自己的执行上下文AO,这时候会放到自己作用域的顶端
  • scope chain[0] --> AO
  • [1]--> GO
  • 函数在查找变量时,遵从作用域链顶端自顶而下查找

EC/AO/VO/GO

EC(Execution call) 执行上下文

AO(active Object) 活跃对象,函数创建时会产生,同时确定其作用域[[scope]]

VO(variable Object) 变量对象

GO(global Object) 全局变量对象,也是VO(G)

代码语言:javascript
复制
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);




ECS = [
    EC(A) = {
        // 链表初始化为 AO(A) -->  VO(G)
        [scope]: VO(G),
        scope.chain: <AO(A), VO(G)>,
        AO(A) : {
            x: 2,
            B: function (z) {}..,
            B[[scope]]: AO(A),	// 函数创建的时候就确定了其作用域,指向当前的环境
        }
    },
    // A函数执行时,EC(G)被压入栈底
    EC(G) = {
        // 全局变量对象
        VO(G) : {
            x: 1,
            A: function (y) {}..,
            A[[scope]]: VO(G),	// 函数创建的时候就确定了其作用域
            c: A(2),
        }
    }
]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JS底层运行机制(成哥版,腾讯课堂有免费公开课)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档