JavaScript作用域
1. 什么是作用域
作用域是代码中的某些特定部分中变量,函数和对象的可访问性。
换句话说,作用域决定了代码区块中变量和其他资源的生命周期和可见性。变量在作用域之外是不可见的。
JavaScript 的作用域包括:
-
全局作用域
-
模块作用域
-
函数作用域
-
块作用域
-
词法作用域
2. 全局作用域
在任何函数、块或模块范围之外定义的变量具有全局作用域。具有全局作用域的变量可以在程序的任意位置访问。
创建全局作用域,
这里分两种情况来说:
- 一种是在具有模块系统的情况下,例如在HTML中,我们可以使用基于AMD或者CMD的模块系统,这时如果要创建全局作用域,需要定义在模块外部,这里的模块本质上就是个闭包函数,也就是在函数外部去创建:
<script>
//定义全局变量
let GLOBAL_DATA = {
value : 1};
(function(){
//使用闭包创建的模块
})()
</script>
console.log(GLOBAL_DATA);
-
当没有模块系统时,创建全局变量会容易很多。在任何文件中的函数外声明的变量都是全局变量。
全局变量贯穿于程序的整个生命周期。 -
另一种创建全局变量的方法是在程序的任意位置使用 window 全局对象:
window.GLOBAL_DATA = {
value: 1 };
这样 GLOBAL_DATA 变量会随处可见。
console.log(GLOBAL_DATA)
- 所有 window 对象的属性拥有全局作用域
一般情况下,window 对象的内置属性都拥有全局作用域,例如 window.name、window.location、window.top 等等。
全局作用域有个弊端:如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样就会 污染全局命名空间, 容易引起命名冲突。
// 张三写的代码中
var data = {
a: 100}
// 李四写的代码中
var data = {
x: true}
这就是为何 jQuery、Zepto 等库的源码,所有的代码都会放在(function(){....})()
中。因为放在里面的所有变量,都不会被外泄和暴露,不会污染到外面,不会对其他的库或者 JS 脚本造成影响。这是函数作用域的一个体现。关于函数作用域我们下面再说。
(function(){
var count = 0;
return function(){
count++;
}
})(