JS 执行环境解析

JS 执行环境

笔记性质
菜鸟初学,为了避免误人子弟,请大神留步勘误 QQ

建议搭配服用: JS Scope / Hoisting

执行环境的基础

以 Function 做为划分不同执行环境Function 于呼叫后,会先建立执行环境,才执行内部程式码只要有 call function 就会建立执行环境,包括递迴、whileLoop只有一个 Global Context (全域环境)

执行环境的种类

全域 Global : 程式开始执行的预设环境函式 : 开始跑函式内部程式码的环境Eval
把一串字串当作指令执行,会先将字串解析成JS,因此效能不佳 (ESLint 不建议使用)

执行环境 堆叠

Browser JS 为 单执行绪
因此每次只能执行一件事,当一个事件在执行时,其他会被丢到执行伫列中。Event Loop 概念 (待整理....)

环境执行流程

Call Stack 特性为 后进先出会先建立 Global Context (全域执行环境) 于 Call Stack 当中执行 a()建立 a() 的执行环境,并放入 Call Stack当中等 a() 的内容执行完毕后,会从 CallStack 回收掉执行 Global Context 的 console.log()
此段不懂可以去此看精美的图
function a() {  var c = 1}a()console.log('123')

执行环境 内容

概念上我们可以把一个 执行环境 想像成一个物件内包含:

Scope Chain [注1]
负责记录每个环境之间切换的关联
记录包含 自己的 VO + 所有上层执行环境的 VO 的集合。VariableObject (VO)
负责记录执行环境中定义的变数、函式、参数,
于建立阶段初始化,执行阶段给与値this
  executionContextObject = {    scopeChain: {},    variableObject: {},    this: {}  }

建立执行环境的背后

建立 Global 全域环境

执行 Function 前,建立执行该Function的环境 分为两阶段

建立阶段

建立阶段,初始化这个环境

除 arguments 外都只是先定义变数 & 函式指标,并没有赋值

进行 Hoisting

初始化 scope chain

判断决定 this 的值 (因此 this 在函式呼叫时才被决定)

建 variableObject

建 arguments object 并给予值

仅参数的值 会在建立阶段就给与检查传入参数,初始化参数的名称,值以及建立参考

将 function 的宣告 加入 variableObject

函式宣告给予指标

将 变数 的宣告 加入 variableObject

变数 / 函式宣告 初始化值为 undefined (没有赋值)

执行阶段

给与値、设定 Function 的参考、逐行解译执行程式码

  function foo(i) {    var a = 'hello';        // 建立阶段 函式表达 不给与 值/指标    var b = function B() { };        // 建立阶段 函式宣告 给与指标    function c() { }   }  foo(22);  // 建立阶段 / 执行阶段  fooExecutionContext = {    scopeChain: { ... },    variableObject: {      // arguments object      // 0: 表第一个传入的参数 1: 表2......      //! 参数的值 会在建立阶段就给与。      arguments: { 0: 22, length: 1 },      i: 22,      a: undefined, // 未给与値      b: undefined,  // 函式运算 不给与値      c: pointer to function c(), // 函式宣告 给与指标      // 执行阶段才给与値 进行覆写建立阶段建立的变数 / 其他不变      a: 'hello',      b: pointer to function B()    },    this: { ... }  }

建立阶段 Function 的不同行为

定义函式又分为三种

透过 new Function 关键字建立函式 (ESLint不建议,不讨论)a 函式运算式 Function Expression
函式表达式,需要等待至执行阶段才会给与值。
var a =  function () {}
b 函式宣告式 Function Declaration
函式宣告会于建立阶段,赋予指标指向该 Function
function b() { }

实际範例

  ;(function () {      // 建立阶段 a 为 函式运算式 未给值 undefined    // 建立阶段 b 为 函式宣告 给予指标 pointer to function b()    console.log(typeof a) // undefined    console.log(typeof b) // function            // 执行阶段 给与值 pointer to function a()    var a =  function () {}     console.log(typeof a) // function         // 执行阶段 给与值 进行覆写    var b = 123     console.log(typeof b) // number         function b() { }        // 执行阶段 给值 a : pointer to function a()    // 执行阶段 给与值 b : 123  }())

建立阶段 函数宣告 & 变数宣告 的优先权

建立阶段: Hoisting 函数宣告 优先于 变数宣告
  // Hoisting 函数宣告 优先于 变数宣告 (不论 Code相对位置)  function a() {}  var a // 并没有重新给值,因此 执行阶段此行不会执行  console.log(typeof a) // function  // 于执行阶段给予值  var b = 1  function b() {}  console.log(typeof b) // number

练习题

请解释

Why 可在宣告前存取 foo [Hoisting]Foo 被宣告 2 次,为什么 foo 是 function 而不是 undefined 或 string ?Why bar is undefined ?
  (function () {    console.log("foo: " + typeof foo)    var foo = 'hey'    console.log("foo: " + typeof foo)    function foo() { return 'hello' }    console.log("bar: " + typeof bar)    var bar = function() { return 'world' }    console.log("bar: " + typeof bar)  }())
Ans: 1.function / 2.string / 3.undefined / 4.function// 建立阶段: 1.函式宣告 给座标、3.函式运算 不给值// 执行阶段: 2. var foo = 'hey'  foo 给值为 string// 执行阶段: 4. var bar = func~  bar 给值为 function

Why 可在宣告前存取 foo
在建立阶段我们就已经将变数建立了 [Hoisting]

Foo 被宣告 2 次,为什么 foo 是 function 而不是 undefined 或 string ?
第一个 log()

建立阶段
函式宣告 给与 指标 // foo: pointer to function foo()执行阶段 var foo = 'hey'
进行覆写建立阶段的变数,因此 foo: 'Hey'

第二个 log()
因为执行阶段会给于值,因此 foo 被改写成 str 'hey'

Why bar is undefined ?
建立阶段还未给与値,因此为 undefined
执行阶段 才会给与値

C() 执行结果为何? Why?

  var c = 1  function c() {    console.log(typeof c)  }  console.log(c)  c()
  Ans: c is not a function    console.log(c) // 1  // 建立阶段 Hoisting c = function pointer  // 执行阶段给予值 先读 c = 1 后执行 c() 此时 c 给值为 1  // 因此 c is not a function

参考资料

andyyou
DavidShariff
PJChENder


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章