js执行上下文时,变量提升,作用域
全局污染
所谓全局变量污染 :定义多个全局变量,函数,对象挂载在window上,如果重复使用则造成变量冲突
如果定义一个全局变量则会在window上挂载这个变量,所有的函数,对象,引用此js文件的都可以使用
1 2 3 4 5 6 7 8 9 10 11 <script> var a = 10 ; console .log(window ); </script> Window a: 10 alert: ƒ alert() applicationCache: ApplicationCache {status : 0 , oncached : null , onchecking : null , ondownloading : null , onerror : null , …} 。。。。。。。
污染 如同衣物沾上污渍,笔墨落入清水。
全局window是大家都能使用,如果在全局挂载变量太多,难免会调用重复的变量,改变其属性或值。
在开发中,多人共同开发,每个人的代码习惯不同,命名方法不同,如果其他人命名一个变量ID,那么,在调用ID时会改变上一个人的ID导致不是自己想要的ID。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <script> var ID = 10 ; console .log(ID); </script> <script> var ID = 2 ; console .log(ID); </script> <script> var ID = 4 ; console .log(ID); </script> <head> <script src="developer_first.js" ></script> <script src="developer_second.js" ></script> <script src="developer_thirdly.js" ></script> / /最后的 </ head>
ID会使用最后调用的js文件
为了避免全局污染,应慎重使用全局变量。了解模块化,或者let 定义的let不在window里 在script内有效
或者函数{}内有效,形成块级作用域
执行上下文 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 在开始说明JS上下文栈和作用域之前,我们先说明下JS上下文以及作用域的概念。 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行。 执行上下文类型分为: 全局执行上下文 函数执行上下文 执行上下文创建过程中,需要做以下几件事: 创建变量对象:首先初始化函数的参数arguments,提升函数声明和变量声明。 创建作用域链(Scope Chain):在执行期上下文的创建阶段,作用域链是在变量对象之后创建的。 确定this的值,即 ResolveThisBinding 作用域 **作用域**负责收集和维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。—— 摘录自《你不知道的JavaScript》(上卷) 作用域有两种工作模型:词法作用域和动态作用域,JS采用的是**词法作用域**工作模型,词法作用域意味着作用域是由书写代码时变量和函数声明的位置决定的。(`with` 和 `eval` 能够修改词法作用域,但是不推荐使用,对此不做特别说明) 作用域分为: 全局作用域 函数作用域 块级作用域 JS执行上下文栈(后面简称执行栈) 执行栈,也叫做调用栈,具有 **LIFO** (后进先出) 结构,用于存储在代码执行期间创建的所有执行上下文。 规则如下: 首次运行JavaScript代码的时候,会创建一个全局执行的上下文并Push到当前的执行栈中,每当发生函数调用,引擎都会为该函数创建一个新的函数执行上下文并Push当前执行栈的栈顶。 当栈顶的函数运行完成后,其对应的函数执行上下文将会从执行栈中Pop出,上下文的控制权将移动到当前执行栈的下一个执行上下文。
1 2 3 4 5 6 7 8 9 10 first ( ) { console .log('first' ) } second ( ) { first() } third ( ) { second() } third()