什么是作用域?
作用域:一个变量可以生效的范围。变量不是在所有地方都可以使用的,而这个变量的使用范围就是我们要说的作用域。
注意:在JavaScript中,划分作用域也是用大括号划分的,但是在JS中能够有效限定作用域的大括号只有函数大括号!
作用域的分类
- 全局作用域(不在任何函数内)
- 全局作用域是最大的作用域
- 在全局作用域中定义的变量可以在任何地方使用
- 页面打开的时候,浏览器会自动给我们生成一个全局作用域 window
- 这个作用域会一直存在,直到页面关闭就销毁了
请看下面示例代码
var a = 10;
console.log(a); //输出结果为 10
function fn(){
console.log(a); // 输出结果也是10
}
fn()
当变量 a 使用 var 进行声明时,此时没有函数大括号包裹着,那么这个变量我们称之为 全局变量
这个全局变量在任何地方都可以访问。
- 局部作用域(在函数内部)
- 局部作用域就是在全局作用域下面有开辟出来的一个相对小一些的作用域
- 在局部作用域中定义的变量只能在这个局部作用域内部使用
- 在 JS 中只有函数能生成一个局部作用域,别的都不行
- 每一个函数,都是一个局部作用域
请看下面示例代码
// 下面这个 num 是一个全局作用域下的变量 在任何地方都可以使用
var num = 100;
function fn(){
// 下面这个 num 变量就是一个 fn 局部作用域内部的变量
// 只能在 fn 函数内部使用
var num = 200
console.log(num) // 输出结果:200
}
fn()
console.log(num) // 输出结果:100
通过上面的代码可以看出:
在函数大括号之中声明的变量,这种变量我们称之为 局部变量
局部变量只能在声明它的作用域之中使用。
我们见惯了常规情况,现在看一个特殊情况:
声明变量时不使用 var 关键字声明:
注意!这是一个不规范的声明方式!不要使用!不要使用!不要使用!
使用之后导致的结果就是:一个局部变量的声明,在全局中也可以被访问!(这样的声明叫做伪全局变量)
请看下面示例代码:
function fn(){
a = 100; //此时声明变量 a 没有使用 var 关键字进行声明
console.log(a); 输出结果为 100
}
console.log(fn()) //输出结果为 100 竟然不会报错!!!
看完上面的示例代码,突然感觉这不是很好嘛?,变量a可以随便使用,不会报任何错误了,在这里,你心中肯定会产生疑问?这是为什么???
那么,请继续往下看,这个写法很危险的!!!
当把局部变量变成伪全局变量时:
你会发现:
- 生命周期变长了,造成一定的负面影响;
- 占据了全局命名空间,造成不可预知的错误
在这里来解释下,生命周期 是什么??命名空间 又是什么???请接着往下看
生命周期(这个变量在内存之中存活的时间)
就是你啥时候都可以访问这个变量!
全局变量和局部变量中的生命周期的区别
- 全局变量:生命周期是和程序同步的,程序不关闭,变量就一直存在;
导致的结果就是会让程序变得更重!如果可能,我感觉还是少设置一点全局变量把!对开发人员都好
- 局部变量:生命周期是和函数执行同步的,函数执行结束,变量就被删除了;
这就是所谓的生命周期,全局变量多了,可能真的会影响到我们程序的运行效率,上面说的伪全局变量就是这个道理。
我们了解完生命周期,接下来来看一下命名空间吧!
命名空间(变量名命名的唯一性)
- 全局变量:命名空间是唯一的,一个页面只有一个
先看一下下面的示例代码:
var a = 100;
function fn(){
// 程序的懒惰原则:函数的大括号之中如果已经有了 var 查找结果,那么就不会计息再查找了
// 这是就近原则
var a = 0;
console.log(a) // 输出结果:0
}
console.log(fn()) // 输出结果:100
为了解决全局之中的命名空间是唯一的这个问题,我们可以把这个变量放在局部,那么就不会占用全局的命名空间了。
- 局部变量:命名空间一个作用域只有一个
可以用匿名函数来解决命名空间的问题
这里有一个问题:我现在要写一大坨代码,和别人的代码要配合 。 这个时候咋写呢???
让匿名函数经历一次运算: 如果函数发生了特定的运算, 那么这个函数就会被当做一个地址;
// fn(); //报错 :fn is not a function;
// var fn = function(){
// console.log("hi");
// }
// fn();
// 用声明的方式 定义函数,会有声明的提升
fn();
function fn(){
console.log("hi");
}
fn();
最后来个总结吧!
1、全局不能访问局部
2、局部可以拿到全局