1. 作用域规定了变量能够被访问的“范围”,离开了这个“范围”,变量就不能被访问。
2. js中作用域分为局部作用域和全局作用域,局部作用域又分为函数作用域和块作用域。
3.1 函数作用域:在函数内部声明的变量,只能在函数内部被访问,如:
<script>
function getfun(){
//局部变量num的声明
let num=3;
console.log(num); //这里能获得num变量
}
console.log(num); //这里不能获得num变量
</script>
3.2 块作用域:在js中使用花括号{}包裹的代码叫代码块,代码块内部声明的变量,外部将有可能被访问,因为var不会产生块作用域,举例一个块作用域,嘿嘿:
<script>
for(let i=1;i<=10;i++){
console.log(i); //控制台输出1~10
}
console.log(i); //显示i未被定义
</script>
但是,如果将let换为var,就不一样了,哈哈:
<script>
for(var i=1;i<=10;i++){
console.log(i); //输出1~10
}
console.log(i); //输出11
</script>
(1)不同代码块之间的变量无法相互访问(但var没块作用域)
(2)let声明的变量会产生块作用域,var变量不会产生块作用域,const常量也会产生块作用域,所以尽量推荐使用let来声明变量
4. 全局作用域
<script>标签或js文件里面最外层的变量叫做全局作用域,在全局作用域里面声明的变量外部也能访问。如:
<script>
//全局作用域下声明的变量
let like=10;
function fn(){
console.log(like); //10
}
fn();
console.log(like); //10
</script>
注意:(1)为window对象动态添加的属性默认也是全局的,不推荐
(2)函数中未使用任何关键字声明的变量为全局变量,不推荐
(3)尽可能少的声明全局变量,防止全局变量被污染
5.作用域链
作用域本质上是底层的变量的变量查找机制。
(1)在函数被调用执行时,会优先查找当前函数作用域中的变量
(2)如果当前作用域查找下找不到则会依次逐级查找父级作用域到全局作用域直到找到
如:
<script>
//全局作用域
let a=1;
let b=2;
//局部作用域
function f(){
let a=1;
//局部作用域
function g(){
a=2;
console.log(a);
}
g(); //调用函数g(),控制台打印2
}
f();
</script>
总结:嵌套关系的作用域串联起来形成了作用域链;
子作用域能访问父作用域(继承),父作用域无法访问子作用域。