关于javascript:JavaScript-中的执行上下文和执行栈

39次阅读

共计 1835 个字符,预计需要花费 5 分钟才能阅读完成。

执行上下文概念

执行上下文就是评估和执行 javascript 代码的环境的抽象概念. 每当 javascript 运行的时候, 它都是在执行上下文中运行

执行上下文的类型

  1. 全局执行上下文: 这是默认的上下文, 任何不在函数外部的代码都在全局上下文中. 它会执行两件事: 创立一个全局 window, 并且设置 this 的值指向这个 window. 一个程序中只有一个全局执行上下文
  2. 函数执行上下文: 每当一个函数被调用时, 都会为该函数创立一个新的上下文. 每个函数都有它本人的执行上下文, 不过都是在函数被调用时创立的. 函数上下文能够有多个, 每当一个新的执行上下文创立时, 它会依照定义的程序执行一系列的步骤.

执行栈

是一种领有后进先出数据结构的栈, 被用来贮存代码运行时创立的所有执行上下文
为了模仿执行上下文栈的行为,让咱们定义执行上下文栈是一个数组:

ECStack = [];

当 javascript 引擎第一次遇到你的脚本时. 它会创立一个全局的执行上下文, 并且压入以后执行栈, 也就是数组 ECStack 中.

ECStack = [globalContext];

每当引擎遇到一个函数调用. 它会为该函数创立一个新的执行上下文并且压入以后执行栈的顶部.

引擎会执行那些执行上下文位于栈顶的函数。当该函数执行完结时,执行上下文从栈中弹出,管制流程达到以后栈中的下一个上下文
当初 javascript 遇到上面的这段代码:

function fun3() {console.log('fun3')
}
function fun2() {fun3();
}
function fun1() {fun2();
}
fun1();
// fun1()
ECStack.push(<fun1> functionContext);
// fun1 中调用了 fun2, 还要创立 fun2 的上下文
ECStack.push(<fun2> functionContext);
// fun2 调用了 fun3 
ECStack.push(<fun3> functionContext);
// fun3 执行结束
ECStack.pop();
// fun2 执行结束
ECStack.pop();
// fun1 执行结束
ECStack.pop();

思考题:

// 比拟上面两段代码,试述两段代码的不同之处
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){return scope;}
    return f();}
checkscope(); // 

// B---------------------------
var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){return scope;}
    return f;
}
checkscope()();

下面两端代码输入值是一样的, 都是 local scope
然而执行上下文栈的变动不一样
第一段代码

ECStack.push(<checkscope> functionContext)
ECStack.push(<f> functionContext)
ECStack.pop()
ECStack.pop()

模仿第二段代码

ECStack.push(<checkscope> functionContext)
ECStack.pop()
ECStack.push(<f> functionContext)
ECStack.pop()

作用域

作用域是程序源代码中定义变量的区域
作用域规定了如果查找变量, 也就是确定以后执行代码对变量的拜访权限.
词法作用域: javascript 采纳的是词法作用域 也就是动态作用域, 函数的作用域是在定义的时候就决定了
动静作用域: 函数的作用域是在函数调用的时候才决定的

看上面例子

var value = 1;
function foo() {console.log(value);
}
function bar() {
    var value = 2;
    foo();}
bar();

如果 javascript 采纳动态作用域.
执行 foo 函数, 先从 foo 函数外部查找是否有局部变量 value. 如果没有, 就依据书写的地位, 查找下面一层代码. 也就是 value 等于 1. 所以后果会打印 1

假如 javascript 采纳动静作用域.
执行 foo 函数. 仍然是从 foo 函数外部查找是否有局部变量 value. 如果没有. 就从调用函数的作用域. 也就是 bar 函数外部查找 value 变量, 所以打印 2

正文完
 0