关于代码执行作用域

关于代码执行作用域

在刷了一天关于变量提升和作用域的题目以后,我打算整理一下现在脑子里的东西(2020年3月19日18:43:35),开始吧。

比如一串代码先执行,首先全局上下文要进一个执行环境栈,如果有var和function,则进行声明+定义,同时会给当前函数设置一个作用域([scope])当前函数创建时候所在的上下文。var的只是提前声明,function会声明+定义。

什么是声明呢?简单来说就是在当前作用域创建一个变量。定义呢就是创建变量和赋值同时完成。

肯定有小伙伴要问了:如果没有var怎么说?如果没有var的话就相当于window里面创建了一个名为xx的属性和属性值。但是值得注意的是用var创建的同时,在window也会创建一个相应的属性

然后代码开始执行,完成变量的赋值,浏览器有个机制:之前声明过的变量,在下面不会再重新声明,所以声明过的变量完成赋值,声明定义过的函数不再创建新的堆(变量提升时候已经完成),然后遇到函数执行,形成一个新的私有的执行上下文。

那么问题来了,私有上下文里面的机制是什么?其实是一样的,但是在进栈的时候,会在全局执行上下文的上面来执行,浏览器的机制。进栈以后,会初始化作用域链,如果有形参的话,要进行形参变量赋值,值得一提的是形参变量属于这个函数的私有变量,然后再进行变量提升,接着进行代码执行。值得一提的是,如果这个函数没有return,那么这个函数的值不能被其他上下文使用。执行完成以后完成出栈,有时不会出栈。

那么现在就谈一下作用域链查找的机制,在当前的执行上下文中,代码在执行的过程中如果遇到一个变量,首先看是否是私有的,如果是的话,则接下来的所有操作都是操作自己的这个变量;如果不是私有的,则按照scopeChain作用域链进行查找,在哪个上下文中找到,当前变量就是谁然后进行操作。就这样一直向上查找,一直找到全局上下文为止。

如果找到全局上下文都找不到,当执行的操作是获取,那么就会报错;如果执行的操作是设置值,相当于给window增加属性

我对作用域链的理解就是将执行环境栈看成是一个大宇宙,全局上下文是太阳系,其中的那些私有的上下文是各种行星,当从行星里找不到一个单位时,会上去一个大环境中去找,直到找到宇宙中,如果是寻找那么找不到就报错,如果是设置的话就相当于在宇宙中创造了一个属性。

下面附上一张图,还有权威解释,好好理解一下。

关于代码执行作用域

手动给图片加个水印吧:from珠峰培训-周啸天。