这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
作用域
01. 作用域
(1)概念
- 作用域就是一套规则,用于确定在何处以及如何**查找变量(标识符)**的规则
- 或者说是在代码运行时,变量的可访问性
(2)两个作用域
- 全局作用域
- 程序的最外层作用域,始终存在
- 定义在全局作用域下的变量就是全局变量
- 全局变量在任何地方都可以使用
- 函数作用域
- 在函数定义时才会被创建
- 定义在局部作用域下(函数内部)的变量就是局部变量
- 局部变量只在局部作用域下生效,且会覆盖同名的全局变量
(3)作用域链
-
当查找(访问)变量时,采取的是一种链式查找的方式,即,从内到外、从下到上的方式,去查找作用域下的变量
- 从当前作用域开始查找
- 如果没有,则由底向上,到最近的一层父级作用域下查找
- 如果没有,则重复上述步骤,直到查找到,或者到全局作用域,则停止
-
我们把这种嵌套的作用域的结构称为**作用域链**
(4)词法作用域
-
词法作用域:在函数被定义的时候,它的作用域就已经确定了
- 和在哪里执行没有关系,因此词法作用域也被称为 静态作用域
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar(); // 1 // 这里 foo() 是在全局作用域下定义的,所以它的外层作用域是 全局作用域 // 与 foo() 在哪里执行时没有关系的, // 所以 bar() 的输出结果为:1
(5)块级作用域
-
简单来说,一对花括号
{}之间的区域就是块级作用域区域 -
且,需要使用
let和const关键字来创建块级作用域var声明的变量没有块级作用域
-
特别的:
在现有浏览器机制中
如果在块级作用域中,遇到
function定义的变量——命名函数(是匿名函数就没事)那么,它定义处的代码之后出现的变量,只对当前块起作用,对外层上下文没有影响
尽量避免在块级作用域中声明函数
console.log(a) // undefined -- 因为变量提示 var a = 0 console.log(a) // 0 if (true) { console.log(a) // f a(){} -- 因为函数提升到当前块级作用域顶部 a = 1 // 这里的 a ,改变的是全局的 a console.log(a) // 1 // 当块级作用域中遇到命名函数,那么其【定义处】之后的代码 // 出现的变量,都将是新的变量,只对当前块级作用域生效,对上一层没有任何影响 function a() {} a = 11 // 这里的 a ,改变的是块级作用域内部的函数 a console.log(a) // 11 } console.log(a) // 1// 以上代码可这样理解 var a1 = 0 if(true) { function a2(){} a1 = 1 a2 = 11 }
全局变量声明后,可以重复使用,但也意味着,在某一处进行了更改,则会影响全局——全局污染
而局部变量时不存在这个问题的,但局部变量又无法重复使用
因此,如果希望有一种变量即可以重复使用,有不会污染全局,就可以使用——闭包(下一篇文章)
本人前端小菜鸡,如有不对请谅解