#### 作用域链
作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。看一个例子
```js
var a = 1
function fn () {var b = a + 1console.log(b)
}
fn()
```### 从代码执行来看
首先在创建fn函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。当调用fn函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链,然后创建活动对象AO并推入执行环境的作用域链。在fn执行完成后,作用域就会被销毁。
JS中的六中数据类型字符型,数值型,布尔型,Null,undefined和对象Object:符合数据类型,对象是属性和方法的集合甚至是另一种类型的对象。
基本数据类型:数值、字符串、null、undefined、布尔
引用数据类型:对象、数组、函数
JS变量的定义统一使用var声明,会在需要的时候自动转型,可以先声明然后赋值通常以;号结尾这是个好习惯。
作用域:执行环境中变量或函数的作用范围分为三类:
全局作用域:页面打开时创建关闭时销毁。
编写在Script标签中的变量和函数在页面的任何位置都可以访问
全局作用域可以被认为是window,因为所有的全集变量和函数都是作为window对象的属性和方法创建的。
局部(函数)作用域:调用时创建,执行完毕销毁,每调用一次创建一个新的,它们之间互不干扰。函数可以访问上层定义的内容但是相邻函数作用域是相互独立的。
ES6之前没有块级作用域是指:定义的对象是全局的windows可查
eg: if (ture){var a =1}console.log(a)能在检测到a的值为1
但是ES6中的话 if(true){let x=1}console.log(x)这种情况是全局访问不了x的值的。
作用域链带scope用途是保证对着执行环境有权访问的所有变量和函数的有序访问。
关于作用域链主要就是进行标识符的查询(变量和函数),标识符的解析就是沿着作用域一级一级的搜索标识符的过程。如果自身作用域中声明该变量就不用使用作用域链
JS的预编译:
预编译是在上下文创建之后js代码执行前的一段时期,在这个时期,会对Js代码进行预处理。全局创建之后会生成会生成变量对象VO,首先寻找变量说明,将var声明的变量作为VO的对象的属性名,值为undefined.然后找函数声明,属性值为函数本身,如果函数名与变量名冲突,函数声明会将变量声明覆盖。
函数预编译:函数上下文创建后,会生成变量对象AO
寻找变量声明,变量作为AO对象的属性名,属性值为undefined
寻找形参,形参作为AO对象的属性名,属性值为undefined
将实参的值赋予形参及替换对象中形参的属性值。
闭包:能够访问到其他函数作用域中的对象的函数,成为闭包。