加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、容器安全、数据加密、云日志、云数据迁移!
当前位置: 首页 > 教程 > 正文

Javascript中的执行上下文如何搭建

发布时间:2023-07-29 11:30:50 所属栏目:教程 来源:转载
导读:   这篇文章主要介绍“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 相继出栈并销毁,代码运行完毕。
 

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章