执行环境(Execution context,简称EC)或执行上下文对象(后面统一用执行上下文表示),它定义了变量或者函数有权访问的其他数据,决定了他们各自的行为。是不是有点不好理解,那我先简单翻译下: js代码执行时所在的环境。继续后面
在JavaScript中执行环境分三种:
那么现在问题来了,平时工作中写的全局变量,函数以及嵌套函数应该不少了吧,每执行一个函数就会创建一个新的函数执行上下文,想想那么多执行上下文是不是有点恐怖,那么js又是如何管理那么多的执行上下文呢?
当执行流执行一个函数时,就会给当前函数创建执行上下文,并且将该执行上下文被推入一个执行上下文栈中(Execution context stack,ECS),在函数执行完之后,执行上下文栈将被弹出,并且把控制器返回给之前执行的执行上下文;
根据工作原理执行上下文栈类似一个数组结构 ,我们模拟执行上下文栈的行为:
- 1 ECStack = []; //先定义执行上下文栈是一个数组:
JavaScript 开始要解释执行代码的时候,最先遇到的就是全局代码,所以初始化的时候首先就会向执行上下文栈压入一个全局执行上下文,用 globalEC表示它,并且只有当整个应用程序结束的时候,ECStack 才会被清空,所以 ECStack 最底部永远有个 globalEC:
- ECStack = [
- globalEC
- ];
现在 JavaScript 遇到下面的这段代码了:
- <script>
- function run3() {
- console.log('run3')
- }
- function run2() {
- run3();
- }
- function run1() {
- run2();
- }
- run1();
- </script>
当执行一个函数的时候,就会创建一个执行上下文,并且压入执行上下文栈,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出。知道了这样的工作原理,让我们来看看如何处理上面这段代码:
- // 伪代码
- // run1() 推入执行上下文栈
- ECStack.push(run1.EC);
- // run1中调用了run2,创建run2的执行上下文 推入执行上下文栈
- ECStack.push(run2.EC);
- // run2还调用了run3,创建run3的执行上下文 推入执行上下文栈
- ECStack.push(run3.EC);
- // run3执行完毕
- ECStack.pop();
- // run2执行完毕
- ECStack.pop();
- // run1执行完毕
- ECStack.pop();
- // javascript接着执行下面的代码,但是ECStack底层永远有个globalContext,直到应用程序退出(例如关闭网页)
执行环境(Execution context,简称EC)或执行上下文对象,它定义了变量或者函数有权访问的其他数据,决定了他们各自的行为。
当执行流进入一个函数时,创建执行上下文对象,然后推入执行上下文栈。是不是感觉跟定义相差太远,难道是《javascript高程程序设计》写错了?
当然不是,执行上下文到底包含了哪些内容所以欢迎阅读下一篇《javascript 之变量对象》。
来源: http://www.cnblogs.com/CandyManPing/p/7775506.html