函数执行(调用)大概步骤
1、创建活动对象AO(Active Object) (上下文)
2、预编译:
scope chain
初始化arguments
初始化形参,讲arguments中的值赋值给形参
找出所有的变量声明,按照变量名加入AO,如果已经存在,忽略。
找出所有的函数声明,按照函数名加入AO,如果已经存在同名变量或者函数,替换。
this初始化
解释执行。
栗子
//1、函数中,所有变量声明,在函数的预编译阶段完成,所有变量的声明与
//实际的书写位置无关
function f(){
console.log(aa);
var aa=5;
console.log(aa);
}
f();
//2、函数中,所有函数声明,在函数的预编译阶段完成,所有函数的声明与
//实际的书写位置无关
function f(){
console.log(haha);
function haha(){
console.log('h1');
}
}
f();
<script>
//3、函数中,如果变量和函数同名,那么,函数将覆盖变量
function f(){
console.log(haha);
var haha=123;
function haha(){
console.log('h1');
}
}
f();
</script>
<script>
//4、函数中,只有函数能够覆盖变量,变量无法覆盖函数。
function f(){
console.log(haha);
function haha(){
console.log('h1');
}
var haha=123;
}
f();
</script>
<script>
//5、函数中,后面的函数声明会覆盖前面的函数声明,并且,忽略参数。
function f(){
console.log(haha);
function haha(a){
console.log('haha1');
}
function haha(a,b){
console.log('haha2');
}
}
f();
</script>
难度++
<script>
//6、但函数预编译后,遇到需要访问的变量或函数,优先考虑自己AO中定义的变量和函数
//如果找不到,才会在其定义的上一层AO中寻找,直到到达GO
var scope ="global";
function f(){
console.log(scope); //undefined
var scope="local";
console.log(scope); //local
}
f();
console.log(scope); //global
</script>
分析:1、脚本运行预编译GO:里面有scope和函数f、分别为undefined和function。执行时GO环境下scope赋值“global”。t:运行、生成t-AO:进行预编译、扫描到了scope变量进行初始化,运行的时候函数内部,第一个scope是undefined,然后是local,紧接着函数作用销毁。
function test(x,x){
console.log(x); //function
x=5;
console.log(arguments); //arguments[1]=5
//arguments 12 5
function x(){
}
}
test(12,13);
分析:GO: 、test:func 、test-AO: 然后初始化arguments,arguments[12,13]。然后arguments对形参赋值。13赋值给了arguments[1]。开始预编译,因为两个形参名为X,后者覆盖了前者。然后x改变了等于5