JS之函数作用域及作用域链

变量作用域

在JavaScript中全局变量的作用域比较简单,它的作用域是全局的,在代码的任何地方都是有定义的。然而函数的参数和局部变量只在函数体内有定义。另外局部变量的优先级要高于同名的全局变量,也就是说当局部变量与全局变量重名时,局部变量会覆盖全局变量。

 var num = 1;            //声明一个全局变量
    function func() {
        var num = 2;        //声明一个局部变量
        return num;
    }
    console.log(func());    //输出:2 
    console.log(num);      //输出:1

注:声明局部变量时一定要使用var,否则,解释器会将该变量当做全局对象window的属性。

函数作用域

在JavaScript中变量的作用域,并非和C、Java等编程语言似得,在变量声明的代码段之外是不可见的,我们通常称为块级作用域,然而在JavaScript中使用的是函数作用域(变量在声明它们的函数体以及这个函数体嵌套的任意函数体都是有定义的)。

function func() {
        console.log(num);           //输出:undefined,而非报错,因为变量num在整个函数体内都是有定义的
        var num = 1;                //声明num 在整个函数体func内都有定义
        console.log(num);           //输出:1
    }
    func();

注:JavaScript的函数作用域是指在在函数内声明的所有变量在函数体内始终是可见的,也就是说在函数体内变量声明之前就已经可用了。

作为属性的变量

当声明一个全局变量的时候,实际上是定义了全局对象window的一个属性。

    var num = 1;            //声明全变量num
    alert(window.num)       //输出:1 声明的全局变量实际上就是声明了一个window对象的属性

javascript有两种作用域:全局作用域;局部作用域/函数作用域;
顾名思义,全局变量在全局作用域,局部变量在局部作用域中。
全局变量网页中所有脚本和函数均可使用。 如果变量在函数内部没有用var声明,则也是全局变量,但不推荐。

作用域链

作用域链是查找一个变量的时候,一层一层的向上形成的查找轨迹。

每个函数都有自己的执行环境,环境内存储了作用域内定义的所有变量。当函数执行时,环境被推入环境栈中,执行完毕后,弹出环境,返回之前的执行环境。

作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问,作用域的前端,始终是当前执行代码所在环境的变量对象(也就是代码里最近的那个)

function foo(a) {
    var b = a * 2;
    function bar(c) {
        console.log( a, b, c );
    }
    bar(b * 3);
}
foo( 2 ); // 2 4 12

标识符解析是沿着作用域链一级一级地搜索标识符地过程。搜索过程始终从作用域链地前端开始,然后逐级向后回溯,直到找到标识符为止(如果找不到标识符,通常会导致错误发生)—-《JavaScript高级程序设计》

参考:https://blog.csdn.net/qq_33939113/article/details/82717240
https://www.cnblogs.com/mrzl/p/4415149.html
https://cloud.tencent.com/developer/article/1339323

原文地址:https://www.cnblogs.com/jessie-xian/p/11596108.html