JS基础巩固系列:【6】理解执行上下文和作用域

执行上下文

执行上下文可以理解为函数执行的环境,每一个函数执行时,都会给对应的函数创建这样一个执行环境。

1
2
3
4
5
6
7
8
9
10
11
var color = 'blue';
function changeColor(){
var anotherColor = 'red';
function swapColors() {
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
}
swapColors();
}
changeColor();

以上代码的执行上下文栈的变化过程
Image text

作用域链

  1. 怎么查看作用域链
    每一个 javaScript 函数都表示为一个对象,更确切地说,是 Function 对象的一个实例。
    Function 对象同其他对象一样,拥有可编程访问的属性。和一系列不能通过代码访问的 属性,而这些属性是提供给 JavaScript 引擎存取的内部属性。其中一个属性是 [[Scope]] ,由 ECMA-262标准第三版定义。
    内部属性 [[Scope]] 包含了一个函数被创建的作用域中对象的集合。
    这个集合被称为函数的 作用域链,它能决定哪些数据能被访问到。
    来源于:《 高性能JavaScript 》;
    如果要通过代码查看一个函数的作用域链,我们可以查看其原型constructor属性中的[[Scopes]]属性
  2. 作用域链是在什么时候生成的
    这个问题我们用两段代码比较下:

    • 第一段

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      var testValue = 'outer';
      console.log('函数声明前', foo.prototype)
      function foo(){
      console.log(testValue);
      console.log('函数执行时', foo.prototype);
      }
      function bar(){
      var testValue = 'inner';
      console.log(bar.prototype);
      foo();
      }
      bar();
      console.log('函数执行完毕', foo.prototype)
    • 第二段

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      var testValue = 'outer';
      function bar(){
      var testValue = 'inner';
      foo();
      console.log(bar.prototype);
      function foo(){
      console.log(testValue);
      console.log(foo.prototype);
      }
      }
      bar();

      根据以上的代码,我们基本可以确认,函数的作用域链,是在js引擎完成初始化上下文执行环境时确认的。