您的位置: 翼速应用 > 业内知识 > web前端 > 正文

详细题解Javascript中的执行上下文

本文给大家带来关于Javascript中的执行上下文解析,给大家分享一道题目,旨在通过对题目的逐渐解析来掌握相关的Javascript知识,希望各位看完这篇文章能对Javascript的执行上下文内容有属于自己的理解,下面一起来看一下。


详细题解Javascript中的执行上下文


详细题解Javascript中的执行上下文


话不多说直接上题目:


function func(value){
    getValue = function(){
        console.log(value);
    };
    return this
}
             
function getValue(){
    console.log(5);
}

Func(1).getValue(); //为什么是1呢?


具体执行分析


执行全局代码,创建全局执行上下文,全局上下文被压入执行上下文栈:


ECStack = [ globalContext ];


初始化全局上下文:


globalContext = {
    VO: {
        func: reference to function func(){},
        getValue: reference to function getValue(){}
    },
    Scope: [globalContext.VO],
    this: globalContext.VO //全局上下文
}


初始化全局上下文同时创建了两个函数,因此也会保存他们父级作用域链在他们的内部属性 [[scope]] 内


func.[[scope]] = [
     globalContext.VO
];
getValue.[[scope]] = [
     globalContext.VO
];


此时开始执行代码,执行到最后的语句时先执行 func 函数,也就创建按步骤 func 函数执行上下文:


●  复制函数 [[scope]] 属性创建作用域链


●  用 arguments 创建活动对象


●  初始化活动对象


●  将活动对象压入 checksfunccope 作用域链顶端。


●  创建this,简单分析:MemberExpression 值为func,func是一个函数对象,理所当然是一个Reference ,其中它的 base value 是 EnvironmentRecord ,所以它的 this 值为 ImplicitThisValue(ref),返回值始终是 undefined ,非严格模式下,其值会被隐式转换为全局对象。


funcContext = {
    AO: {
        arguments: { // 数组
            0: 1,
            length: 1
        }
    },
    Scope: [AO, globalContext.VO],
    this: undefined
}


可能有人会有疑问,func 里的 getValue 呢?,因为它并没有变量申明,因此他其实是一个属性的赋值操作,在后面运行时才会被执行。


创建函数执行上下文后压入执行上下文栈


ECStack = [
    funcContext,
    globalContext
];


函数开始执行,此时就是为什么最后输出是1的关键了,第一句赋值操作,那么就需要沿着执行上下文去找变量 getValue,那么我们就来看 funcContext 中的作用域,首先找到 funcContext.AO 显然并不存在 getValue 这一属性,那么沿着作用域链往上找,找到了globalContext.VO ,找到了 getValue ,这时候就会给全局作用域下的 getValue 属性重新赋值,赋的是一个函数的传新版本,也就重新创建了函数作用域,将这个全新的 getValue 函数的父级作用域链保存在它在他们的内部属性 [[scope]] 内:


getValue .[[scope]] = [ funcContext.AO, globalContext.VO ];


然后才继续返回 this ,查找 funcContext 的 this ,即返回undefined;func 执行上下文出栈


ECStack = [ globalContext ];


继续执行Func(1).getValue(),前半部分返回了 undefined ,此时系统隐式转换为全局变量对象,从全局变量对象中找到 getValue 属性。这时候我们发现 getValue 早已不是当年那个少年,执行全新的 getValue 的函数执行上下文并入栈:


getValueContext = {
    AO: {
        arguments: { // 数组
            length: 0
        }
    },
    Scope: [ AO, funcContext.AO, globalContext.VO ],
    this: undefined
} ECStack = [
    getValueContext,
    globalContext
 ];


函数开始执行,发现即将输出 value ,沿着作用域去找,结果getValueContext.AO 中并没有这个属性, 继续往下找找到 funcContext.AO,在形参中 找到了 value 那么就输出对样的值,也就输出了1。下一步函数执行完毕,getValueContext 和 globalContext 相继出栈并销毁,代码运行完毕。以上就是全部习题的解析,大家学会了吗?翼速应用平台内有更多相关资讯,欢迎查阅


我来说两句

0 条评论

推荐阅读

  • 响应式布局CSS媒体查询设备像素比介绍

    构建响应式网站布局最常见的是流体网格,灵活调整大小的站点布局技术,确保用户在使用的幕上获得完整的体验。响应式设计如何展示富媒体图像,可以通过以下几种方法。

    admin
  • 提升网站的性能快速加载的实用技巧

    网站速度很重要,快速加载的网站会带来更好的用户体验、更高的转化率、更多的参与度,而且在搜索引擎排名中也扮演重要角色,做SEO,网站硬件是起跑线,如果输在了起跑线,又怎么跟同行竞争。有许多方法可提升网站的性能,有一些技巧可以避免踩坑。

    admin
  • 织梦CMS TAG页找不到标签和实现彩色标签解决方法

    织梦cms是我们常见的网站程序系统的一款,在TAG标签中常常遇到的问题也很多。当我们点击 tags.php 页的某个标签的时候,有时会提示:“系统无此标签,可 能已经移除!” 但是我们检查程序后台,以及前台显示页面。这个标签确实存在,如果解决这个问题那?

    admin
  • HTML关于fieldset标签主要的作用

    在前端开发html页面中常用的标签很多,今天为大家带来的是关于HTML中fieldset标签主要的作用说明,根据技术分析HTML

    admin

精选专题