JS作用域与作用域链
函数表达式和字面量函数声明的区别?
字面量声明会发生提升 成为window对象下的属性 定义时发生在函数声明的时候
数字(Number)字面量 可以是整数或者是小数,或者是科学计数。
字符串(String)字面量 可以使用单引号或双引号。
布尔字面量,其值只有两个。分别为true和false。
表达式字面量 用于计算,使用运算符进行计算,如算术、位、条件、比较及逻辑运算符等。
数组(Array)字面量 定义一个数组:
对象(Object)字面量 定义一个对象:
函数(Function)字面量 定义一个函数:
以下是各种字面量的例子:
3.14 1001 123e5 // 各种数字字面量
“Jhon Doe” ‘Jhon Doe’ // 字符串字面量
true false // 布尔字面量
5 + 6 (3 + 4) * 9 // 表达式字面量
[40, 100, 1, 5, 25, 10] // 数组字面量
{firstName:“John”, lastName:“Doe”, age:50, eyeColor:“blue”} // 对象字面量,就是一个对象的实例
function myFunction(a, b) { return a * b; } // 函数字面量
**函数表达式不会发生提升** 定义发生在赋值的时候
3.浏览器执行JavaScript的过程
3.1分析语法错误
基本语法检测,有没有基本的语法错误,例如中文标点符号等
3.2 预编译
全局预编译:
1. 生成一个GO对象
2. 分析var关键字声明,如果GO中不存在,则添加,值为undefined,如果存在则忽略
3. 分析function声明,如果存在则覆盖,否则添加
函数预编译
1. 函数运行的一瞬间 ( 定义 运行),生成一个AO(active Object)对象作用域
2. 分析函数的形参,将形参作为AO对象的属性名,值为实参的值,如果没有传递实参,值为undfined
3. 分析var关键字声明,如果AO中不存在,则添加,值为undefined,如果存在则忽略
4. 分析function声明,如果AO中存在则直接覆盖,否则添加
3.3 根据分析出的GO对象去执行代码
浏览器根据预编译分析出来的AO,GO对象逐行执行代码,
注:分析过了变量、函数声明的就不用管。后续只需要管赋值即可
4.Scope
执行期上下文对象的集合
官方解释:[[scope]]每个JavaScript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供JavaScrip引擎读取,[[scope]]就是其中一个
4.1全局作用域
预编译分析出来后的GO就称之为全局作用域,其内的属性可以在全局进行调用
4.2函数作用域
预编译分析出来后的AO就称之为函数作用域,其内的属性仅可以在该函数内部进行调用
4.3注意点
ⅰ. 函数定义时 Scopes属性中已经存储了GO
ⅱ. 函数运行时 Scopes属性会继续添加当前函数预编译后的AO
ⅲ. 函数在每次运行时,都会产生一个独一无二的AO,并在函数运行结束后销毁
5.作用域链
官方解释:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式叫做作用域链
函数嵌套时,每一个作用域形成嵌套的过程,(如一个大的GO里面,嵌套了多个AO)形成作用域链。因为形成作用域时入栈操作,所以作用域链的查找机制是由上往下进行执行的。