理解js中的作用域

执行期上下文(AO):函数在运行时(或预编译时),会创建一个叫执行期上下文问的一个内部对象。AO或GO,他定义了一个函数的执行环境(用来做变量/函数的提升等等),函数执行完毕则会销毁。
作用域:每一个函数对象都有一个[[scope]]属性,他内部存储了执行期上下文的集合,也就是我们说的作用域。这个集合是一种链式结构,叫做作用域链

作用域链的形成过程

当函数被定义时,这个函数的[[scope]]属性会指向它的上一级函数的[[scope]]属性的值的引用
但函数被执行时,这个函数的[[scope]]属性会在他的最上层添加他自己的执行期上下文(AO)。
当函数执行完成后,他自己的执行期上下文(AO)会被销毁
当查找某个变量或方法时,会从[[scope]]属性的最上层一直向下寻找。即先找它自己的AO,若未找到,则再向他的上一级函数的寻找

举个栗子:

function a(){
    function b(){
    	var b = 123
    }
    var a = 10
    b()
}
var glob = 100
a()

1.a函数定义时,它的[[scope]]会指向它的上一级即全局的执行期上下文(GO)
在这里插入图片描述
2.a函数执行时,他的[[scope]]会在他的最上层(最首位)添加自己的执行期上下文(AO),其祖先级依次下移(后移)。
在这里插入图片描述
3.此时,b函数被定义,它的scope属性指向它的上一级,即a的scope的引用。
在这里插入图片描述
4.b函数被执行时,会形成自己的AO,并置于其作用域链的最顶端(首部),其余依次下移(后移)。
在这里插入图片描述
5.此时,当某个函数内使用某个变量时,会在其作用域链上(scope chain)依次寻找.
注:一个函数得AO对象上,还包括this、arguments等属性,此处不一一介绍

作用域的分类

全局作用域:全局作用域指的是在全局起作用的作用域。一般指上面所说的GO
局部作用域(函数作用域):局部作用域指的是在局部起作用的作用域。一般函数的作用域都是局部作用域,即上面的AO
块作用域:一般而言,块作用域指的是以{}包含的内容快,函数或变量只在它所在的的快内起作用。es5中不存在块作用域,es6新增了块作用域。for循环和if语句的{}属于块作用域

举个例子
当我们使用if语句时,在if语句的内部定义了变量

var foo = true
if(foo){
    var c = 2
    console.log(c) // 2
}
console.log(c)  // 2

变量c只在if所在的代码块中使用,因此将他声明在if语句内部是很必要的,但是通过var声明的变量最终都会属于外部作用域。相当于以下代码

var foo = true
var c
if(foo){
    c = 2
    console.log(c) // 2
}
console.log(c)  // 2

所以就需要一些其他的结构或语法来实现块级作用域。在es6中新增了let/const,用来声明变量
let会把变量绑定在它所在的块中。
const用来声明常量,也会形成块级作用域。

var foo = true
if(foo){
    let c = 2
    console.log(c)
}

console.log(c)  // 报错

由于let会形成块级作用域,所以if(){}外接受不到c变量,所以会报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值