百度面试题
案例:
function bar(){
return foo;
foo = 10;
function foo(){
}
var foo = 11;
}
console.log(bar());
讲解:
一、预编译
(1) 创建GO对象
GO{
bar : function bar(){}
}
二、GO的预编译完成,开始执行程序
(1) 执行语句console.log(bar());
执行该语句时,bar()函数需要进行预编译
切记:预编译发生在函数执行的前一刻
预编译时:
a、创建AO对象
AO{
}
b、寻找形参和变量声明,并将形参名称和变量名称作为属性,并赋值为undefined
AO{
foo : undefined
}
c、形参和实参进行统一,由于实参为空,所以保持原样
AO{
foo : undefined
}
d、查找函数声明,并将赋值函数体
AO{
foo : function foo(){}
}
程序执行时:
a、return foo; //function foo(){}
注意该return 语句,如果某个函数直接返回return语句,那后续的程序则不执行。
b、foo = 10;
AO{
foo : 10
}
c、function foo(){}//预编译时已执行,不再执行
d、var foo = 11;//变量声明整理提升,只执行foo = 11;
AO{
foo : 11
}
结果为:function foo(){}
案例二【案例一的变形】
console.log(bar());
function bar(){
foo = 10;
function foo(){}
var foo = 11;
return foo;
}
讲解:
一、预编译
(1) 创建GO对象
GO{
bar : function bar(){},
foo : 10
}
二、GO的预编译完成,开始执行程序
(1) 执行语句console.log(bar());
执行该语句时,bar()函数需要进行预编译
切记:预编译发生在函数执行的前一刻
预编译时:
a、创建AO对象
AO{
}
b、寻找形参和变量声明,并将形参名称和变量名称作为属性,并赋值为undefined
AO{
foo : undefined
}
c、形参和实参进行统一,由于实参为空,所以保持原样
AO{
foo : undefined
}
d、查找函数声明,并将赋值函数体
AO{
foo : function foo(){}
}
程序执行时:
a、foo = 10;
AO{
foo : 10
}
b、function foo(){}//预编译时已执行,不再执行
AO{
foo : 10
}
c、foo = 11;
AO{
foo : 11
}
d、return foo;//返回值
11
结果为:11
案例三
a = 100;
function demo(e){
function e(){}
arguments[0] = 2;
console.log(e);
if(a){
var b = 123;
function c(){}
}
var c;
a = 10;
var a;
console.log(b);
f = 123;
console.log(c);
console.log(a);
}
var a;
demo(1);
console.log(a);
console.log(f);
讲解:
一、预编译
(1) 创建GO对象
GO{}
(2) 形参和变量声明名称为GO对象属性,赋值undefined
GO{
a : undefined
}
(3) 函数声明,赋值函数体
GO{
a : undefined,
demo : function demo(e){
function e(){}
arguments[0] = 2;
console.log(e);
if(a){
var b = 123;
function c(){}
}
var c;
a = 10;
var a;
console.log(b);
f = 123;
console.log(c);
console.log(a);
}
}
二、GO的预编译完成,开始执行程序
(1)a = 100;
GO{
a : 100,
demo : function demo(e){
function e(){}
arguments[0] = 2;
console.log(e);
if(a){
var b = 123;
function c(){}
}
var c;
a = 10;
var a;
console.log(b);
f = 123;
console.log(c);
console.log(a);
}
}
(2) demo(1);//执行该语句时,创建AO对象
a、创建AO对象
AO{}
b、形参和变量声明名称作为AO属性,并赋值undefined
AO{
e : undefined,
c : undefined,
a : undefined,
b : undefined
}
c、形参和实参进行统一【实参的值赋给形参】
AO{
e : 1,
c : undefined,
a : undefined,
b : undefined
}
d、寻找函数声明,赋值函数体
AO{
e : function e(){},
c : function c(){},
a : undefined,
b : undefined
}
预编译完成,执行函数demo(1)
a、function e(){}//预编译时已执行
b、arguments[0] = 2;
arguments表示用于存放实参的变量,表示e = 2
AO{
e : 2,
c : function c(){},
a : undefined,
b : undefined
}
c、console.log(e); //打印结果 2
d、if(a){
var b = 123;
function c(){}
}
a为undefined,所以不执行if条件中的程序
e、var c;//预编译时已执行
f、a = 10;
AO{
e : 2,
c : function c(){},
a : 10,
b : undefined
}
g、var a;//不再执行
h、console.log(b);//结果为undefined
i、f = 123;//该语句表示f为全局变量,因此会存放到GO对象中
GO{
a : undefined,
demo : function demo(e){
function e(){}
arguments[0] = 2;
console.log(e);
if(a){
var b = 123;
function c(){}
}
var c;
a = 10;
var a;
console.log(b);
f = 123;
console.log(c);
console.log(a);
},
f : 123
}
AO{
e : 2,
c : function c(){},
a : 10,
b : undefined
}
j、console.log(c);//结果为function c(){}
【此处需要注意:目前在if条件语句中不可以定义函数体,因此此处应打印的是undefined,例子的问题】
k、console.log(a);//10
(3) console.log(a);//结果为100
(4) console.log(f);//123
案例四
console.log(test);
function test(test){
console.log(test);
var test = 234;
console.log(test);
function test(){}
}
test(1);
var test = 123;
一、预编译
1、创建GO对象
GO对象>AO对象
2、GO对象的构成,会针对于script中所有的程序而言,不会同AO创建时,仅仅针对于函数内部,因此在全局范围类查找形参和变量声明
GO{
test : undefined
}
3、找到函数声明,并赋值函数体
GO{
test : undefined
}
4、找函数声明,因此全局对象为:
GO{
test : function test(){}
}
预编译完成,开始执行程序
二、程序执行
(1) console.log(test);
执行结果会从GO对象中获取值,结果为function test(){}
(2) test(1);//去调用以下函数
function test(test){
console.log(test);
var test = 234;
console.log(test);
function test(){}
}
执行该程序时,会创建AO对象
AO{
}
根据AO对象的预编译四部曲
a、查找形参和变量声明,并将形参名和变量名作为属性,值为
undefined
AO{
test : undefined
}
b、将实参和形参进行统一
AO{
test : 1
}
c、查找函数声明,并赋值函数体
AO{
test : function test(){}
}
编译完成,内部程序执行
a、console.log(test);//function test(){}
b、var test = 234;
AO{
test : 234
}
c、console.log(test);//234
d、function test(){};//预编译已执行,不再执行
因此最终的AO对象为
AO{
test : 234
}
(3) var test = 123;
全局对象为:
GO{
test : 123
}