- JS没有块级作用域 ES6新增块级作用域概念
全局作用域
- 在页面打开时被创建 在页面关闭是被销毁
- 在script标签内写的都为全局作用域 在页面内的任意位置都能访问
```
<script>
var a = 1
</script>
```
- 全局作用域有一个全局 window对象,代表一个浏览器窗口 由浏览器创建,可以直接调用
- 全局作用域声明的变量会在window对象中保存
函数作用域
- 函数在调用时会创建一个函数作用域 在调用完成后会被销毁
- 每调用一次函数都会创建一个新的函数作用域,之间是相互独立的
- 函数作用域中可以访问函数作用域中的变量 ,在函数中声明的变量只能在函数中访问
- 在函数作用域中访问变量 函数会先找此函数内部声明变量 然后依次向上级查找
作用域理解
-
执行期的上下文
-
当函数代码执行的前期(预编译)会创建一个执行期的上下文的内部对象AO(作用域)
-
这个AO对象是在函数预编译期间创建的 在函数调用之前创建
-
在全局代码执行的前期会创建一个预编译的上下文对象GO
// 函数声明 function functionName(arg1, arg2, ...){ <!-- function body --> } // 函数表达式的典型格式: variable = (arg1, arg2, ...)=>{ <!-- function body --> }function add(e,f){ console.log(e,f,a) //e() f() undefined var f = 3 var e = 3 function f(){ } function e(){ } //函数的表达式 var a = ()=>{} console.log(e,f) } add(1,2) // 1 创建AO对象 // 2 找形参和变量声明 将变量和形参的名 当做AO对象的属性名 值为undefined // 3 实参形参统一 // 4 在函数体中找函数 值为undefined AO = { e:undefined 1 fn, f:undefined 2 fn, a:undefined }作用域链
- 会被保存到一个隐式的属性中去[{scope}] 这个属性用户访问不到 但是的确存在 让js引擎来访问 里面存储的就是作用域链 AO GO 的集合
let global function a() { function b() { var aa = 123 bb = 0 } var bb = 123 b() } a()
graph LR; a['a定义 scope']-->SCOPE; SCOPE-->GO['全局预编译产生 '];graph LR; a['a函数内部 ']-->作用域链顶端是自己的AO; 作用域链顶端是自己的AO-->GO['第二层是GO '];graph LR; b['b函数内部 ']-->作用域链顶端是自己的AO; 作用域链顶端是自己的AO-->AO['第二层是a函数的AO ']; AO['第二层是a函数的AO ']-->第三层是GO; -