一、作用域与作用域链
一、作用域分类
在JS中,作用域分三类:全局作用域,局部作用域,块级作用域。下面一一说明:
全局作用域:数据定义在函数外边就是全局作用域;
局部作用域:数据定义在函数里面就是局部作用域;
块级作用域:let与{}同时出现,才会出现块级作用域;let来声明变量,{}来包裹着数据。
二、三者的区别与联系
1)在全局作用域下(函数外部)访问变量,不能访问到局部作用域(函数内部定义的变量)的变量;
2)在局部作用域内(函数内部),可以访问全局的变量;
3)块级作用域需要let与{}同时共存,与前两者没有太大的关系。
三、作用域链概念
作用域链是一种数据查找机制,与执行上下文有关,它会一层层的去找嵌套到的数据变量,先找自己本身内部的,再去找其父级函数中的。
二、上下文与上下文栈
一、执行上下文概念
每个代码在调用的时候,都会生成执行上下文,这里的代码分为两大类:全局代码和函数代码。全局代码执行时生成全局执行上下文;函数代码执行时生成的是函数执行上下文。只要代码跑起来了,那么就默认进入了全局代码,一执行就生成了全局执行上下文。
二、执行上下文理解
1、执行上下文:
(1)每个代码在调用时,都会产生一个执行上下文;
(2)代码可以分成两类:函数代码(函数内部的代码);全局代码(打开页面就会执行的代码)。
2、全局代码和函数代码:
函数代码:在函数里面的代码叫函数代码(或者局部代码)。
全局代码:页面跑起来,默认进入的就是全局代码。
3、全局执行上下文,函数执行上下文:
当执行全局代码时,产生一个全局执行上下文;全局执行上下文只有一个。
当执行函数代码时,产生一个函数执行上下文。而每调用一次函数,都会产生一个函数的执行上下文件。函数执行上下文可以有N个。
4、执行上下文的作用:
给全局代码或局部代码提供数据。数据包含变量和函数。
5、父级函数:
父级函数指的是本身函数的上一级函数,比如对于定义的全局变量(函数)一样,其对应的父级函数指的是全局代码。
6、执行上下文中组成:
1,全局执行上下文由全局的变量和函数组成。
2,局部执行上下文由本函数内部的变量,arguments,内部定义的函数;以及父级函数的执行上下文。
三、执行上下文栈概念
只需要知道栈都是“先进后出”,在执行函数时,先是全局变量,生成的全局执行上下文扔到底部,随着函数代码执行会生成函数执行上下文在全局的顶部,当最终代码执行完后再弹出栈。
四、执行上下文栈理解
1、全局执行上下文位于栈底,当调用一个函数,就产生一个局部的执行上下文,这个局部的执行上下文要压栈,当这个函数执行完,这个执行上下文就要出栈。
2、在函数中使用变量的值,由执行上下文栈分析,它是如何确定?
执行上下文中保存数据有两部分组成:1)是自己定义的变量,2)是父级函数的执行上下文。
对于全局代码来说,就只有第一部分,自己定义的变量也就是全局变量
答:首先在自己定义的变量中找,找不到的话就去父级函数的执行上下文去找,如果找不到变量就报错。
3、为什么函数内部的变量,在函数的外部无法访问?
答:从执行上下文与执行上下文栈的角度来分析,因为定义在函数内部的变量都是局部变量,不是全局变量;而在函数外部访问的代码是全局代码,必须去全局执行上下文中寻找变量,而全局变量中并没有,所以无法访问。