什么是作用域

作用域,通俗的来讲就是你的代码在运行时,各个变量函数和对象的可访问性(可产生作用的区域)。作用域分为全局作用域,函数作用域和块级作用域。

全局作用域

在任何函数,块或模块发布为之外定义的变量具有全局作用域。可以在程序的任意位置访问到全局变量。
ok,让我们来看一段代码

var a=10;
function aaa(){
    alert(a)
}
aaa()//10
console.log(window.a)//10

a为外部变量即全局便力量,所以可以直接访问到,结果为10,window.a正确的读取到了值,那么就可而说在window对象中变量时全局变量,她的作用域就是全局作用域。我们都知道,ES6之前声明变量只有var,如果我们创建一个变量没有用var会发生什么呢

var a=10;
function aaa(){
    alert(a)
}
aaa()//10
console.log(window.a)//10

和上文一样,所以没有var声明的变量也是全局变量

函数作用域

函数作用域意味着在函数中定义的参数和变量在函数内的任何位置都可见,但在函数外部不可见

function aaa(){
    var a=10;
    console.log(a)//10
}
console.log(a)//a is not defined

用var声明的变量只是函数作用域,用var声明的变量被提升到其作用域的顶部。通过这种方式,可以在声明致歉访问他们

function aaa(){
    console.log(x)
    var x=1
  }
  aaa()//undefined

这种事不会发生在let中。用let声明的变量只能在定义后访问

function aaa(){
    console.log(x)
    let x=1
  }
  aaa()//x is not defined

事实证明,var已经开始变得过时了

块级作用域

最新的ES6标准中新增了let和const的变量声明,let和const声明的变量可以受到块级作用域的约束,只能在它定义的块中访问。
看看下面这段关于let块范围的代码

let a=1;
{
    let a=3;
}
console.log(a)//1

在{}声明的let变量只在该块中有效

作用域链

在JS中,函数是可以允许嵌套的。即,在一个函数中声明另一个函数

   funciton A(){
        var a=1;
        function B(){
            var b=2;   
    } 
}

对于A来说,A函数在执行的时候,会创建A函数的作用域,那么函数B在创建的时候,会引用A的作用域,类似下面这样
一.png

函数B在执行的时候,其作用域类似于下面这样:
二.png

从上面的两幅图中可以看出来,函数B在执行的时候,是会引用函数A的作用域的。所以,像这种函数作用域的嵌套就组成了所谓的函数作用域链。当在自身作用域内找不到该变量的时候,,会沿着作用域逐步向上查找,若在全局作用域内部仍找不到该变量,则会抛出异常。

Last modification:October 22nd, 2019 at 09:57 pm
如果觉得我的文章对你有用,请随意赞赏