什么是作用域
JS的函数作用域,将作用域拆开来看,“作用”表示读写操作,函数可以读取代码,改写代码;“域”表示空间,范围,区域。
预编译过程
函数预编译:
创建一个GO对象 --> Global Object
找变量声明作为AO的属性名,并赋值为undefined;(若名称相同则写一个并赋值undefined);
找函数声明,赋值为函数体(若函数名与上面某个变量相等时,则用函数体覆盖);
全局预编译:
创建一个AO对象 --> AO:执行期上下文 Activation Object
找形参和变量声明,将变量名和形参名作为AO的属性名,并赋值为undefined;(若名称相同则写一个并赋值undefined);
将形参和实参统一(将实参值赋给AO中与形参相同的属性);
找函数声明,赋值为函数体(若函数名与上面某个变量相等时,则用函数体覆盖);
步骤
1、逐行解读过程中,当碰到表达式的时候,就会用表达式修改预解析的值;表达式是=、+、-、*、/、参数(注意,参数也是表达式,参数可以被修改)
2、预解析的时候,遇到重名的变量名称,字母,值留下一个;
3、预解析时,当变量碰到函数的名称一致的时候,值留下函数块。因为预解析的时候,变量其实是未定义的状态
4、逐行解读代码时,碰到函数,如果没有调用,表示函数没有执行。此时直接略过,直到有表达式才能改变变量的值。
5、所有变量,在正式运行代码之前,都会提前赋一个值;未定义。所有函数,在预解析的时候,都是函数块;
6、逐行解读代码时,是从上到下,从函数内部到函数外部的执行过程
解析
<script>
var a = 20;
var fun = function fun(){};
function fun1(){
console.log(b);//undefined
var b = 30;
console.log(a);//20
var d = 20;
function fun2(){
console.log(d);//20
d = 30;
console.log(d);//30
}
fun2();
}
fun1();
console.log(fun);
</script>
GO{
a : 20,
fun : function fun{},
}
fun1 AO{
b : 20,
d : 20,
}
fun2 AO{
d : 30,
}