JavaScript的作用域

Posted 司徒炼

tags:

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

javascript的作用域

作用域总共有两种模式,词法作用域动态作用域

词法作用域是由开发者在写代码时,将变量和块作用域写在哪里而决定的。

动态作用域是运行时确定的。

JavaScript只有词法作用域,也就是我们说的作用域链,一层一层的嵌套,但this机制很像动态作用域,它也是在运行时决定的。

function foo(){
    // 词法作用域 2  -- 动态作用域 3
    console.log(a); 
}

function bar(){
    var a = 3;
    foo();
}

var a = 2;
bar();

这段代码,以词法作用域来看会输出2,如果是动态作用域的模型,会输出3,因为动态作用域是在运行时决定的,当foo()无法找到a的变量引用时,会顺着调用栈在调用foo()的地方去找a,而不是在词法作用域链上去找a,而foo是在bar里调用的,在bar里找到了值为3的a,所以动态作用域的模型会输出3。

上面只要了解就够了,接下来主要是说函数作用域的事

function foo(){
    var a = 1;
    console.log(a); // 1
}

function bar(){
    var a = 2;
    console.log(a);// 2
}

foo();
bar();

从这里可以看出,在不同的函数中,相同名字的变量,但它们并不是同一个变量,这就是函数作用域。

接下来看稍微复杂的

function bar(){
    var a = 2;
    console.log(a);// 2

    function foo(){
        var a = 1;
        console.log(a); // 1
    }
    foo()
}

bar();

经过这两段代码,可以知道不管函数是否嵌套,里面的同名变量都是互不影响的。

函数作用域是如何查找变量的

var a = 1;
var b = 2;
var c = 10;

function bar(){
    b = 10; // 通过LSH引用,找到了全局作用域的b,再赋值
    var c = 20;
    
    function foo(){
        console.log(a); // 1
        console.log(c); // 20
    }
    
    foo()
}

bar();
console.log(b); // 10

词法作用域在查找变量是往作用域一层一层找的。

foo函数要输出a,会先在自己的作用域里找a这个变量,找不到,就会去父级作用域,这里是bar的作用域找,但是很明显,依然找不到,所以再到上一层作用域,这时已经到全局作用域了,发现找到了,于是就输出a的值,如果全局作用域也没有找到就会报错。

而foo在找c的时候,已经在bar的作用域找到了,所以就不会再去全局作用域找了。

而bar的b,也是这样,在自己的作用域找不到,就去它的父级作用域找。

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

JS---闭包

JS 作用域及作用域链

JS 作用域及作用域链

JavaScript ES6 的let和const

Javascript代码片段在drupal中不起作用

初入AngularJS基础门