前言
Js 中的全局作用域、局部作用域,以及 ES6 中的块级作用域,还有一些帮助理解的实例
一、作用域相关概念
作用域:一个变量的可用范围
- 全局作用域:在全局作用域内声明的变量叫全局变量
- 局部作用域/函数作用域: 在局部作用域(函数内声明)声明的变量叫局部变量,函数的参数也是局部变量
- 块级作用域(ES6 中): 在 ES6 中,一组花括号括起来的区域就是一个块级作用域。
- 使用 let 或者 const 声明的变量,只在对应的块级作用域中生效
- 对于嵌套的块级作用域,内层的块级作用域可以使用外层的块级作用域变量,外层的作用域不能使用内层作用域的变量。
- 需要注意的是 块级作用域针对的变量是使用 let 或者 const 进行声明的, 对于使用 var 声明的变量并不存在块级作用域的规则。 var 声明的变量作用域只有全局作用域和局部作用域
二、作用域的一些注意事项
- 对于未声明的变量直接赋值, js 会在全局作用域自动地帮你声明。
- 变量声明提升:该变量会自动提升到当前作用域的最顶部
- 对于同一个语句,自动声明和变量声明提升是同时存在的吗?
- 答案是否定的,如果有变量提升,说明这个语句的变量已经且只能是使用了 var 进行声明,就自然不存在自动声明这一说法了。
- 如果有自动声明,自动声明会自动的在全局作用域声明,自动地在最头部,因此也用不着进行变量声明提升了。
三、作用域的一些实例
- 对于未声明的变量直接赋值, js 会自动在全局作用域帮你声明。即使是在函数的内部
function a(){
x = 1;
}
a(); // 这一步是执行函数,不可缺少的,不执行这个函数的话,x 相当于没有在函数中初始化操作。
console.log(x); // 1
- 注意当声明语句和赋值语句在其他的语句之后时,变量的提升和 js 的自动声明,会改变代码的运行顺序,使得结果发生变化
var a = 5;
function fn(){
console.log(a); // undefined
a = 8;
var a; // 这里进行了声明,所以这里的 a 是局部变量,变量提升到当前作用域的最顶部。
console.log(a); // 8
}
fn();
a++;
console.log(a); // 6
var a = 5;
function fn(){
console.log(a); //5
a = 8;
// var a; // 与上面不同的是这里注释了函数内部变量 a 的声明,所以在这里的 a 就成了全局变量。
console.log(a); //8
}
fn();
a++;
console.log(a); //9
- 始终记得执行的顺序是按顺序执行的,但是要记得
- 自动声明始终是提升到全局作用域(没有声明,直接赋值的语句就会自动声明)
- 函数提升是整体提升
- 变量声明提升是将声明提升到当前作用域的最顶部
- 总结起来就是要当心声明语句,和没有声明就直接赋值的语句,在其他语句之后的时候要注意可能会改变整体的执行顺序,看起来和代码的执行顺序不一样。执行的结果也会出现差异
// 变量声明提升:自动提升到当前作用域的最顶部
var x = 5;
function a(){
console.log(x); // undefined
var x = 100; // 变量声明提升:自动提升到当前作用域的最顶部,只是声明提前,赋值并没有提前
}
a();
console.log(x); //5
// 当存在全局变量和局部变量的时候,优先使用自己的局部变量
var x = 5;
function a(){
var x = 100;
console.log(x); // 100
}
a();
console.log(x); // 5
// 产生覆盖的情形
var x = 5;
console.log(x); //5
function a(){
x = 100; // 没有声明,直接赋值,会提升到全局作用域声明。然后产生覆盖。
console.log(x); // 100
}
a();
console.log(x); //100
- 易错点
// 报错,没有声明的错误。 在声明前直接使用,因为执行顺序,并没有自动的在全局进行声明
console.log(a); // 报错
a = 10;
//变量声明提升
console.log(a); // undefined
var a = 10;
总结
对作用域,全局作用域,局部作用域,块级作用域进行了总结,并列举了一些易错的实例。