JS中作用域和作用域链

什么是作用域?

作用域是指在程序中定义变量的区域,该区域决定了代码区块中变量或函数的生命周期和其可见性。
大白话来说,就是一个变量能不能被访问或引用,是由它的作用域决定的。

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
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容