什么是作用域?
作用域是指在程序中定义变量的区域,该区域决定了代码区块中变量或函数的生命周期和其可见性。
大白话来说,就是一个变量能不能被访问或引用,是由它的作用域决定的。
function fn () {
var a = 'ok'
}
fn()
console.log(a) // Uncaught ReferenceError: a is not defined
从上面列子中可以看出,在最外层区域中获取变量a报错,变量a指在fn()作用域中生效。所以作用域是独立的区域,隔离变量,不同作用域下同名变量不会有冲突。
ES6 之前作用域分全局作用域和函数作用域
ES6 后新增块级作用域,可通过新增命令let 和const来提现。
全局作用域、局部作用域和块作用域
(1)在代码中任何地方都能访问到的对象拥有全局作用域。
- 最外层函数和最外层函数外面定义的变量拥有全局作用域。
- 所有未定义直接赋值的变量自动声明为拥有全局作用域
- 所有windows对象的属性拥有全局作用域。eg:windows.location
(2)在函数内定义的变量则属于函数作用域,又称局部作用域。局部作用域内的变量只能在自身作用域内被访问。
eg:
function func() {
if (1) {
var a = 123
}
console.log(a)
}
func()
// print: 123
// 局部声明的var变量a,在func作用域中都可访问
(3)ES6 中引入了 let 与 const,与 var 不同的是。之前的例子中,在大括号(包括纯粹的大括号、if、while、for)间用 var 定义的变量处在全局作用域。如果我们用 let 与 const 在大括号中定义,变量将处于块作用域。
eg:
function func() {
if (1) {
let a = 123
}
console.log(a)
}
func()
// VM695:6 Uncaught ReferenceError: a is not defined
// 块作用域,用const、let声明,只在{}这个块中有效
作用域链
当一个变量在当前作用域无法找到时,便会尝试寻找其外层的作用域,如果还找不到,再继续往外寻找(只会往外寻找,不会寻找兄弟作用域,更不会往内寻找)。这种如同链条一样的寻找规则便被称为作用域链。
eg:
var name="a";
function test(){
var name="b";
function fun1(){
var name="c";
console.log(name) // c
}
function fun2(){
console.log(name) // b
}
fun1();
fun2();
}
test();
// 申明的变量name,在作用域链中查找,本作用域中找不到,将继续向往寻找
// eg: fun1 => text => 最外部
// print:
//c fun1 作用域中,name 在fun1作用域中找到name的值,完成搜索,返回name:c
//b fun2 作用域中,name 在fun2作用域中没有找到name 的值,向往查找test作用域,找到name的值,返回搜索:name:b
网友评论