JavaScript的作用域和上下文

Posted xjy20170907

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript的作用域和上下文相关的知识,希望对你有一定的参考价值。

作用域在函数定义时就已经确定了,执行上下文环境在函数调用时才确定。在全局作用域和函数作用域中会创建执行上下文环境(有闭包存在时,一个作用域存在两个上下文环境也是有的)。函数每调用一次都会产生一个新的执行上下文环境。但是处于活动状态的执行上下文环境只有一个,这是一个压栈出栈的过程。

执行上下文:函数每调用一次,都会产生一个新的执行上下文环境,因为不同的调用可能就有不同的参数。

let a = 10, fn,       // 1、进入全局上下文环境
     bar = function(x) 
         let b = 5
         fn(x + b)     // 3、进入fn函数上下文环境
     
fn = function(y) 
    let c = 5
    console.log(y + c)


bar(10)                 // 2、进入bar函数上下文环境

首先(数字1注释),执行代码之前,首先创建全局上下文环境(活动状态)如下:

// 全局上下文环境
a: undefined
fn: undefined
bar: undefined
this: window

之后开始执行代码,代码到10行之前,上下文环境中的变量都在执行过程中被赋值如下:

// 全局上下文环境
a: 10
fn: function
bar: function
this: window

然后执行到bar(10) ,跳转到bar函数内部,执行函数体语句之前,在bar函数内会创建一个新的执行上下文环境如下,并且将bar执行上下文环境压栈。

// bar执行上下文环境
b: undefined
x: 10
arguments: [10]
this: window

然后执行到数字3注释那里,调用fn函数,执行函数体语句之前,会创建一个新的执行上下文环境如下,并且将fn执行上下文环境压栈。

// fn执行上下文环境
c: undefined
y: 15
arguments: [15]
this: window

在上边步骤中,fn执行完毕后,调用fn函数生成的fn上下文环境出栈,被销毁。然后bar执行完毕后,调用bar函数生成的上下文环境出栈,被销毁。然后剩下全局上下文环境,出栈销毁。具体步骤如下图:

技术图片

作用域:在javascript中除了全局作用域每个函数也作为一个作用域,在外部作用域无法访问内部作用域中的变量。

作用域链:如果要取得一个变量得值,首先会在当前的作用域中寻找,如果没有,就会到外层作用域中寻找,再没有在向外层的作用域中找,找到了就结束了,找不到就报异常了,就形成了作用域链。

每个函数作为一个作用域,如果出现函数嵌套函数,则就会出现作用域链。JavaScript的作用域在被执行之前已经创建,之后后再去执行时只需要按照作用域链去寻找即可。

自由变量:比如变量a,是在fn函数作用域使用,但是并没有在fn作用域声明,而是在别的作用域声明,这就是自由变量。

 

以上是关于JavaScript的作用域和上下文的主要内容,如果未能解决你的问题,请参考以下文章

深入理解javascript原型和闭包(13)-作用域和上下文环境

JS的Scope

Javascript 之 作用域和闭包

JavaScript作用域和闭包

javascript数据类型--- 函数对象之作用域和作用域链

JavaScript高级JavaScript的运行原理:V8引擎,JS代码执行原理,作用域和作用域链面试题