• 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作用域声明,而是在别的作用域声明,这就是自由变量。

  • 相关阅读:
    20150316--TP-01
    20150314--TP-02
    20150314--TP-01
    20150313+微信-全
    表单/iframe与video标签
    图像/超链接标签
    HTML列表与表格
    JAVA新的一天
    MySQL常用函数
    php基础--来自网页转载
  • 原文地址:https://www.cnblogs.com/xjy20170907/p/11423292.html
Copyright © 2020-2023  润新知