作用域链:
定义:函数产生就有,继承自己所在空间的作用域链。函数调用,会在自己的作用域链头部插入新的作用域对象,函数调用完毕,函数作用域链头部取出作用域对象。
全局作用域空间对象:
1.window 可以放全局变量
2.全局代码执行顺序:
2.1先扫描var
2.2再扫描function
2.3执行其他非var 非function开头的语句
局部作用域空间对象:
局部代码执行顺序:
1.1先扫描var +形参
1.2实参赋值
1.3再扫描function
1.4执行其他非var 非function开头的语句
块级作用域空间对象(例如:if语句,for循环等):
语句块不会产生新的作用域空间,但会对预编译产生影响。
1.块级作用域下变量不能被重复声明,暂时性死区
2.块级作用域下的函数,提升变量,但不提升函数值
3.语句执行顺序:
3.1 扫描function 开头,实现函数值提升
3.2 执行非var 非function 语句
重点理解:
注意:函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。不然会报错。
预编译:
1.函数预编译:
1.创建AO对象--Activation Object(执行期上下文):AO{ };
2.找形参和变量声明,将变量和形参名作为AO属性名,即变量提升过程,值为undefined。
3.将实参的值放到形参中去。
4.在函数体里面找函数声明,值赋予函数体
<script type="text/javascript">
function test(a,b) {
console.log(a);
c=0;
var c;
a=3;
b=2;
console.log(b);
function b() {}
function d() {}
console.log(b);
}
test(1);
/*形实函运
1.创建AO对象--Activation Object(执行期上下文):AO{ };
2.找形参和变量声明,将变量和形参名作为AO属性名,即变量提升过程,值为undefined。
AO{
a:undefined;
b:undefined;
c:undefined;
}
3.将实参的值放到形参中去
AO{
a:1;
b:undefined;
c:undefined;
}
4.在函数体里面找函数声明,值赋予函数体
AO{
a:1;
b:function b(){};
d:function d(){};
}
*/
</script>
全局预编译:
1、生成一个GO对象--Global Object{},GO===window
2、变量提升
3、函数提升
<script type="text/javascript">
console.log(test);
function test(test) {
console.log(test);
var test=234;
console.log(test);
function test() {}
}
test(1);
var test=123;
/*
1、生成一个GO对象--Global Object{},GO===window
GO{ }
2、变量提升
GO{
test:undefined;
}
3、函数提升
GO{
test:function test(){}
}
*/
</script>