乐趣区

理解JavaScript作用域

1. 什么是作用域?

作用域是指定义变量的区域。

2. 作用域有什么作用?

作用域规定了如何查找变量,也就说当前代码对变量的查找权限。

3.JS 中有几种作用域?

1. 全局作用域
全局作用域是最外围的一个环境,可以在代码中任何地方访问到。在浏览器中全局作用域就是 window,因此在全局中声明的变量和方法就是 window 的属性和方法。

接下来我们看个????

var name = "global";
var num = 100;
function test() {
    var inner_name = "test";
    g_name = "global too";
    console.log(name); //global
    console.log(num); //100
}
console.log(inner_name); //inner_name is not defined
console.log(g_name); //global too
test();

从上面的例子中,我们能看出全局声明的变量在哪里都可以访问到,我们在 test 函数中创建了一个局部变量 inner_name,想在外部访问它,但是结果报出一个没有声明的错误,由此可见外部环境不能访问内部环境的变量和函数。在函数 test 中有一个变量 g_name,它没有用 var 进行声明,并且它可以在函数外部进行访问,这个变量拥有全局作用域,不声明就直接给变量赋值是一种错误的做法,应该避免。

2. 局部作用域
在局部作用域中,局部作用域与全局正好相反,局部作用域只能访问在固定的代码片段中访问到。局部作用域也就是函数作用域。

3. 块作用域
在 ES5 中,是没有块级作用域这个概念的,举个例子:

for(var i=0;i<5;i++) {....}
console.log(i); //5

由上述例子可见,JS 不同于 Java 和 C ++ 的地方是没有块级作用域,在大括号之后依旧可以访问变量。为了解决这个问题,ES6 引入了 let、const 两种声明的方法。这两种声明方法可以将 {} 变为块级作用域,看个例子。

//let
for(let i=0;i<5;i++) {} 
console.log(i); //i is not defined
//const
{
    const name = "const";
    console.log(name); //const
}
console.log(name);//name is not defined

4. 动态作用域和静态作用域

JS 采用的是静态作用域,不是动态作用域。举个例子来说明一下,看下面代码。

var i = 10;
function test() {console.log(i); //10
}
function foo() {
    var i = 20;
    test();}
test();

静态作用域是在函数声明时决定的,动态作用域是在函数调用决定的。
——我们可以假设一下,JS 采用的是动态作用域,在 test 函数执行时,首先在 test 的函数中找 i 这个变量,没有找到于是去上一级作用域中查找,在 foo 函数中找到 i 这个变量,输出 i 应该得到 20,但是得到的值是 10。
——我们再假设,JS 采用的是静态作用域,在 test 函数执行时,在 test 函数中没有找到 i 这个变量于是去上一级作用域中查找,因为 test 是在全局作用域中声明的,所以上一级作用域也就是全局作用域。在全局变量找到了 i 这个变量,输出 i 的值是 10。

以上就是对 JS 作用域的基本理解,如有错误与缺失,请指正,谢谢。

参考链接:

  • https://github.com/mqyqingfen…
  • https://segmentfault.com/a/11…
退出移动版