上一个专题我们讲了javascript 的作用域 我们知道作用域类似 帮派地盘一样的东西
这次我们将要说一说 执行上下文,有的书中也叫 执行环境
我们先看几个简单的例子
console.log(csdn); 直接运行这行代码返回的什么?
*****************************************
console.log(csdn); 直接运行这行代码返回的什么?
var csdn;
*****************************************
console.log(csdn); 直接运行这行代码返回的什么?
var csdn = tomihaohao;
答案:
1. 直接报错
2.undefined
3. undefined
这里涉及到几个知识点:第一个 javascript在运行时 变量的赋值,第二个 变量的提升置顶
我们开始说一说第一个,我这里帮大家总结了一下,大家发现没有js中的赋值一开始,无论是变量还是 函数表达式,注意是函数表达式,一开始都会赋值成undefined; 而 this 和 函数的声明则会直接赋值,也就是这一个赋值的阶段 就是 执行上下文 或者叫做 执行环境
第二个知识点 就是 变量的置顶 ,意思就是
console.log(csdn);
var csdn = tomihaohao;
******************************
会分解成
var csdn;
console.log(csdn);
csdn = tomihaohao;
下面我们在看看函数中的执行上下文
function csdn(a){
console.log(arguments); //[10]
console.log(a);//10
}
csdn(10);
从这里可以看出:函数每当它被调用一次,都会产生一个新的上下文 执行环境。
下面我们在看一个有意思的东西
var a = 10;
function csdn(){
console.log(a);
}
function tomihaohao(f){
var a = 20;
f();//这里是10 不是 20;
}
tomihaohao(csdn);
为什么是10 不是 20 ,请大家一定记住 函数 是在定义的时候 注意是定义的时候不是调用的时候,就已经确定了函数内部自由变量的作用域。
下面我们来总结一下
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个
与之关联的变量对象(variable object) ,环境中定义的所有变量和函数都保存在这个对象中。虽然我们
编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
通俗简单点的来说: 在执行代码之前 要把所有要用到的变量 拿出来赋值一次,有的直接赋值 ,有的直接赋值成undefined。
上面就是所有上下文环境的内容,但是又有一个问题 在执行JS代码的时候 可能会调用很多次函数 产生 无数个执行上下文环境 那么多执行上下文环境应该如何处理呢?
从这里开始我们将要介绍执行上下文栈
执行全局代码时会产生一个执行上下文环境每次调用函数都又会产生执行上下文环境,当函数调用完成之后,这个上下文环境及其中的数据
下面我们来看看一个例子
var a = 10;
var fn-1;
var fn-2 = function(){ return 15; };
fn-1 = function(){ var b = fn-2() return b; };
fn-1();
首先在代码未运行时 我们先进入的全局环境
a:undefined;
fn-1:undefinded;
fn-2:undefined;
this:window;
然后执行代码到最后一行之前,上下文的环境变量都在执行的过程中进行赋值
a:10;
fn-1:function;
fn-2:function;
this:window;
执行最后一行代码以后 上下文环境进入到 fn-1的执行环境在fn-1 内部代码执行之前
a:10;
b:undefined
fn-1:function;
fn-2:function;
this:window;
下面运行fn-1内部的代码 当运行到 fn-2的时候 我们又进入了 fn-2的执行环境,在fn-2运行完以后 我们又返回 fn-1的执行环境,fn-1的代码执行完成以后 我们就返回 原来的全局执行环境
但是 这种情况是一种比较理想的情况 ,后面我们看看闭包