
2.1.4 变量的作用域
同其他编程语言一样,JavaScript的变量同样,拥有作用域,如果在作用域外使用变量会获取不到变量,以至于产生错误。同样,JavaScript的变量也分为全局变量和局部变量两种类型。
1)全局变量:在函数外定义的变量,可以在所有的HTML文件和脚本中使用,例如:

这段代码可以在控制台输出“a+b、a、b”,输出如图2.3所示。

图2.3 样例输出2.3
2)局部变量:在函数内声明的变量,只能在局部范围(函数内部)使用,例如:

这段代码可以在控制台输出“a+b”但是输出“a”“b”时会报错,输出如图2.4所示。

图2.4 样例输出2.4
3)不加var或者let声明的变量:在2.1.3节中介绍过,不加var或者let声明的变量实际上是给Window对象添加了一个不可配置的属性,既然它是整个浏览器窗口的属性,那它一定是可以作用于整个页面的,因此即使不在函数作用域中用var关键字声明,该变量也是全局变量,例如:

这段代码可以成功输出“a+b”“a”“b”,输出如图2.5所示。

图2.5 样例输出2.5
4)代码块中使用var关键字定义的变量:代码块一般指的是花括号中包含的语句。最常见的代码块是if和for语句中的语句块,而这些语句块中的变量指的是在这些代码块中用var关键字定义的变量,这些变量是可以在代码块外的作用域内起作用的,例如:

这段代码能够正确输出“i”和“sum”的值,输出如图2.6所示。

图2.6 样例输出2.6
值得注意的是,代码块中的函数只能在其代码块所在的作用域内使用。如果代码块位于函数中,则声明的变量为局部变量,只能在本函数中使用。而用let声明的函数只能在代码块中生效,在代码块以外是不能生效的。
5)var和let的区别:let关键字是在ES6的JavaScript中新规定的关键字,其目的是解决var关键字的一些缺陷,可以认为是更规范、更先进的var。let缩小了var的作用域,用let声明的变量只能在代码块中生效,在代码块以外的范围是不能生效的,否则使用时会报错。

输出如图2.7所示。

图2.7 样例输出2.7
用let定义的关键字在作用域外是不能被调用的,否则就会报错。而且用let定义的变量是不存在变量提升现象的,关于变量提升在后面的章节中将会详细介绍。