作用域和作用域链

一、作用域

js中的作用域,简单来说就是变量和函数的起作用范围,js中有三种作用域:

全局作用域

全局作用域中的所有变量和函数都能在任何地方被访问到,所有直接写在script标签内或单独的js文件中的变量和函数,都是属于全局作用域。

全局作用域中有一个window对象,在全局作用域中定义的所有变量和函数,都会变成window的属性和方法。

let a = 10;
function foo(){
    console.log(a);
}

console.log(window.a); // 10
window.foo(); // foo

上面的代码中,变量a和函数foo的作用域就是全局作用域,它们在声明的时候,被当做window对象的属性和方法保存在了window对象里面。

函数作用域

在js中,每声明一次函数,就会创建一个函数作用域,范围是函数的形参及其内部的变量和函数。

function foo(){
   let a = 10;
   function bar() {
       console.log('bar')
   }
}

console.log(a); // a is not defined
bar(); // bar is not defined

在这个例子里,变量a和函数bar都是在函数foo里面声明的,所以它们的作用域就是在函数foo内部,foo外部无法访问到(这里先不讲闭包)。

块级作用域

在ES6之前,是没有块级作用域的,只有全局作用域和函数作用域,在ES6引入了let和const之后,才有了块级作用域。

块级作用域是由{…}包裹的一片区域,里面的变量只能在{…}内部被访问到。

{
    let a = 10;
    let foo = function (){
        console.log("foo");
    }
    function bar(){
        console.log("bar");
    }
}

console.log(a); // a is not defined
foo(); // foo is not defined
bar(); // bar

可以看出,用let声明的变量a和函数foo都不能被外部访问,而使用函数声明式的bar却可以被外部访问。这样说明要使得块级作用域起作用,就必须使用let或者const声明(这里不讨论let和const的区别)。

块级作用域还有一些特性,比如不存在变量提升,变量不能重复声明,这些都是let和const的特性导致的。

二、作用域链

先来看一个经典的图:

在这里插入图片描述

这个图里里面存在三层的作用域,最外层的是全局作用域,第二层是函数foo的作用域,第三层是函数bar的作用域,这个三层作用域就形成了层级嵌套的关系。

接着看下面这个例子:

let a = 10;
function foo(){
    let b = 20;
    function bar(){
        let c = 30
        function baz(){
            console.log(a + b + c);
        }
        baz();
   }
   bar();
}
foo(); // 60

这里也有层级嵌套的作用域,函数baz在自己的作用域中没找到变量a,b,c,就到其父作用域bar函数作用域中查找,找到了变量c,然后继续往bar的父作用域foo函数作用域中查找,找到了变量b,继续往全局作用域中查找,找到了变量a,这时候才结束查找。

看了上面的例子,大概就能知道作用域链是个什么了,作用域链就是这一层层嵌套的作用域组成的,本层作用域查不到变量,就往外层查找,直到找到第一个符合的变量就不查找了,要是找到全局作用域也没找到,则报变量未定义的错误。

let a = 10;
function foo(){
    let a = 20;
    function bar(){
        console.log(a);
    }
    bar();
}
foo(); // 20

上面这个例子就说明了第一个符合的变量是什么意思,函数bar在foo作用域中找到了变量a,就不会继续往更高一层的全局作用域中查找。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值