预编译面试题!
1、预编译知识点(引用)
首先,做这类题目需要掌握四个知识点:
(1)、执行期上下文:
当函数在执行前一刻,会创建一个执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境(1.初始化函数的参数arguments,AO,2.创建作用域链3.确定this的值),函数每次执行时对应的执行上下文一定是独一无二,所以多次调用一个函数会导致创建多个执行期上下文,当函数执行完毕,它所产生的的执行上下文被销毁。
(2)、函数预编译(AO):
从函数执行的前一刻开始:
2.1、创建一个函数的AO对象(Activation Object),执行期上下文对象;
2.2、函数的形参,成为AO对象的属性,值为实参的值,若未传值,值为undefined
2.3、将var关键字声明的变量,成为AO对象的属性,值为undefined,遇到重名,不做任何变化;
2.4、将function声明的函数(函数声明)成为AO对象的属性,值为函数体,重名直接覆盖;
(3)、全局预编译(GO):
3.1、创建一个函数的GO对象(Global Object),执行期上下文对象;
3.2、将var关键字声明的变量,成为AO对象的属性,值为undefined,遇到重名,不做任何变化;
3.4、将function声明的函数(函数声明)成为AO对象的属性,值为函数体,重名直接覆盖;
(4)、预编译前奏:
4.1、 imply global : 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量归全局(window)所有;
4.2、一切声明的全局变量,全是window的属性;
2、做题思路小结
其次,要分析每一步的情况(分三步走):
(1)、当有了script标签就会出现GO环境;分析全局中声明var 和function
添加至GO当中,注意上面的GO中的三句话,还有将所有未声明直接赋值的给到全局变量;
(2)、从函数执行的前一刻开始,就会出现AO环境分析全局中声明var 和 function 添加至AO当中,注意上面的GO中的三句话,还有将所有未声明直接赋值的给到全局变量;
(3)、由上到下由左往右,执行代码,(有赋值有传参需要重点注意),分析每一步有没有赋值情况,没有的话找AO拿,AO没有则找GO拿,自己有则不找别人要;
3.例题如下(代码表示):
最后,纵观全局和局部,看特殊一步步走:
(具体题目具体分析)
eg1:
function fn(a){ // 传值 a:1
console.log(a); //fn
var a = 123; // AO a:undefined
console.log(a); //123
function a(){} // AO a: function a(){}
console.log(a); //123
var b =function(){} // b : undefined;
console.log(b); //fn
function d(){} // AO d : function d(){}
}
fn(1);
// 首先分析一下GO
// GO{
// 全局变量只用分析全局预编译
// a:function a(){}
//
// }
// AO{
// 当函数调用时出现局部变量预编译
// a:1(被覆盖)
// (a:undefined,(被覆盖))
// a:function a(){},
// b:undefined,
// d:function d(){}
// }
eg2:
function test(a,b) { //传值1
console.log(a); //1
c = 0; // AO undefined
var c ; //c:0
a = 3 ; // AO undefined
b = 2 ; // AO undefined
console.log(b); // 2
function b(){ }
function d(){ }
console.log(b); //2
console.log(d); //function d(){}
}
test(1);
// 首先分析一下GO
// GO{
// 全局变量只用分析全局预编译
// test:function test(){}
// c:undefined
// a:undefined
// b:undefined
// }
// AO{
// 当函数调用时出现局部变量预编译
// a:1
// c:undefined
// b:function b(){}
// d:function d(){}
// }
eg3:
function test(a,b){
console.log(a); //function a(){}
console.log(b); //undefined
var b =234;
console.log(b); //234
a=123;
console.log(a); //123
function a(){}
var a ;
b=234;
var b = function(){}
console.log(a); //123
console.log(b); //function (){}
}
test(1);
// 首先分析一下GO
// GO{
// 全局变量只用分析全局预编译
// test:function test(){}
// 直接 赋值未声明直接给到全局变量
// a:undefined
// b:undefined
// }
// AO{
// 当函数调用时出现局部变量预编译
// c:undefined
// b:undefined
// a:function a(){}
// }
eg4:
global = 100;
function fn() { //未传值
console.log(global);//undefined 找AO要
global = 200;
console.log(global);//200
var global = 300;
}
fn();
var global;
// 首先分析一下GO
// GO{
// 全局变量只用分析全局预编译
// fn:function fn(){}
// 直接 赋值未声明直接给到全局变量
// global:undefined(不变)\200
//
// }
// AO{
// 当函数调用时出现局部变量预编译
// global:undefined
// }
eg5:
function bar() {
return foo;
foo = 10;
function foo() { }
var foo = 11;
}
console.log(bar()); //function foo(){}看return里面的没有的话找AO要
// 首先分析一下GO
// GO{
// 全局变量只用分析全局预编译
// bar:function bar(){}
// 直接 赋值未声明直接给到全局变量
// fool:undefined\10
// }
// AO{
// 当函数调用时出现局部变量预编译
// foo:function foo(){}
// foo:undefined(去掉)
//
// }
eg6:
a = 100;
function demo(e){
function e(){}
console.log(e) //function e(){}
arguments[0] = 2;
console.log(e) //2
if(a){
var b = 123;
function c(){}
}
var c;
a = 10;
var a;
console.log(b) //undefined
f = 123;
console.log(c) //undefined
console.log(a) //10
}
var a;
demo(1)
console.log(a) //100
console.log(f) //123 没有找全局要
// 首先分析一下GO
// GO{
// 全局变量只用分析全局预编译
// a:undefined
// demo:function demo(){}
// 直接 赋值未声明直接给到全局变量
// a:undefined\100\10(不变)
// f:undefined\123
// }
// AO{
// 当函数调用时出现局部变量预编译
// e:1(被覆盖)
// e:function e(){}
// b:undefined
// c:function c(){}
// c:undefined(去掉)
// a:undefined
// }
4、总结
预编译题目一定要分析透彻,仔细观察每一步代码,结合理论知识和实际例子多加练习一定会掌握明白的,小编初次学习的时候也一遍懵逼,现在好多了哈哈哈哈!!!