JS核心知识点梳理上下文作用域闭包this上
引言满满的干货,面试必bei系列,参考大量资料,并集合自己的理解以及相关的面试题,对JS核心知识点中的作用域、闭包、this、上下文进行了梳理。由于篇幅有限,这里只对我认为最重要的知识做了介绍,一些常识性的东西大家可以参考高程。 上下文(execution context)又叫执行环境,环境。 执行环境定义了变量或者环境有权访问的其他数据,据定了它们的各自行为 --高程一个函数执行的时候,会产生一个属于自己的执行环境。环境里面有一个变量对象variable object(VO),OA里面存放着环境中定义的所有变量和函数,作用域链(scope chain),this。函数执行,环境产生被推入环境栈,函数执行完,环境出栈并被销毁(闭包例外),把控制权返回给之前的执行环境。 作用域js中的作用域是静态作用域,静态作用域又叫做词法作用域,采用词法作用域的变量叫词法变量。词法变量有一个在编译时静态确定的作用域。词法变量的作用域可以是一个函数或一段代码,该变量在这段代码区域内可见(visibility);在这段区域以外该变量不可见(或无法访问)。词法作用域里,取变量的值时,会检查函数定义时的文本环境,捕捉函数定义时对该变量的绑定。--wiki作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。--你不知道的javascript作用域就是执行的时候,给环境变量赋值的一种规则,这种规则在函数定义的时候就已经确定了,和运行无关。js只有全局作用域和函数作用域,没有块作用域。 变量提升我们把定一个变量的行为分为两个过程,声明和定义 var a = 1//实际执行的是下面两步var a a = 1var的变量声明会提升,没有var就是全局变量,let没,const有变量提升var的函数声明和赋值都提升 a //undefined 因为a的声明已经提升到最上面了var a = 1f() //alert 1function f () { alert (1)}有几个特殊的地方虽然平时不会这么写,但是面试题会遇到: 函数体中,return后面的代码不进行变量提升,但是return下面的代码要进行变量提升不管条件是否成立,都要进行变量提升;匿名函数不进行 变量提升;如果变量名字发生重复,那么不再重复声明,但是要重新定义;执行环境和作用域的关系很多人都分不清楚执行环境和作用域的关系。其实很简单,作用域和上下文完全是两个不相干的东西。作用域是一种规格,声明函数的时候就已经确定了。执行环境是函数执行的时候产生的,函数在执行环境中执行。大家看下面例子 alert(a) //a is not defined执行的时候VO里面没有a,因为根据VO作用域链【windows】,按照规则找不到a。 var a = 1alert(a) // alert 1执行的时候,根据规则,从VO作用域链【windows】头部window作用域开始找a,找到a了,a为1,则vo中a设置为1,所以alert 1 var a = 1function foo() { var a = 100 alert(a) }foo() // alert 100执行的时候,根据规则,从VO作用域链【windows-foo】头部foo作用域开始找a,找到a了,a为100,则vo中a设置为100,所以alert 100 var a = 1function foo() { alert(a) }foo() // alert 100执行的时候,根据规则,从VO作用域链【windows-foo】头部foo作用域开始找,没找到a。根据规则,沿上层作用域(也就是window)开始找,找到a了,aw为1。则vo中a设置为1,所以alert 1 ...