JS底层运行机制

17 篇文章 0 订阅

想要了解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)

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),
        }
    }
]

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js 是一款轻量级的前端框架,采用 MVVM 架构,本质上是一个响应式的系统,通过观察者模式的方式,实现了数据与视图之间的双向绑定。Vue.js 的实现原理主要包括以下几个方面: 1. 数据响应式 Vue.js 基于 ES5 的 Object.defineProperty() 方法,实现了双向绑定的核心机制。当一个 Vue 实例被创建后,Vue 会遍历这个实例的 data 对象属性,将这些属性通过 Object.defineProperty() 方法转化为 getter 和 setter,并在 getter 方法中建立一个依赖收集的机制,记录所有依赖这个属性的 Watcher,当属性值发生变化时,依赖收集器会通知相关的 Watcher, Watcher 会更新视图。 2. 模板解析与生成虚拟 DOM Vue.js 的模板采用了类 HTML 的语法结构,Vue 的编译器会将其转换成虚拟 DOM,并将其与 Vue 实例进行绑定,当 Vue 实例数据发生变化时,Vue 会重新生成虚拟 DOM,并与之前的虚拟 DOM 进行比较,得出需要更新的部分,最终通过真实 DOM 更新视图。这个过程需要用到 diff 算法,用来尽可能地复用页面已有的元素,减少重绘重排的开销。 3. 组件化开发 Vue.js 将页面抽象成一个一个的组件,每个组件都有自己的作用域、模板、数据等属性。当组件数据发生变化时,Vue.js 会重新生成组件对应的虚拟 DOM,并对比之前的虚拟 DOM,最终只更新变化的部分,通过这种方式提供了组件级别的性能优化。 总之,Vue.js 实现了一种基于数据的响应式机制,通过虚拟DOM进行DOM操作,最终生成所需要显示的页面。Vue.js组件化开发的方式可以提高代码的可维护性和可扩展性,框架底层的实现优化可以提高页面的性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值