预编译
预编译前奏:
- imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局变量所有。
eg:a = 123;
eg:var a = b = 123; - 一切声明的全局变量,全是window的属性。
eg:var a = 123;===>window.a = 123;
引例:
<script type = "text/javascript">
function fn(a){
console.log(a);
var a = 123;
console.log(a);
function a(){
}
console.log(a);
var b = function(){
}
console.log(b);
function d(){
}
fn(1);
}
//function 123 123 function
</script>
预编译发生在函数执行的前一刻
四部曲
1.创建AO对象 (Activation Object)(执行期上下文)
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3.将实参和形参统一
4.在函数体里面找函数声明,值赋予函数体
例题A的解题过程:
AO{
a:undefined,
b:undefined,
}
|
AO{
a:1,
b:undefined,
}
|
//查找函数声明
AO{
a:function a(){},
b:undefined,
d:function d(){}
}
|
//代值
//这一步开始走函数内部,变量声明提升、函数声明整体提升,优先执行的就不用再执行了,可以直接跳过。
AO{
a:123,
b:function(){}
d:function d(){}
}
</script>
练习题:
<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 2 2
//解题过程:
AO{
a:undefined,
b:undefined,
c:undefined,
}
|
AO{
a:1, //这里虽然有两个形参,但只有一个形参,1只和a对应
b:undefined,
c:undefined,
}
|
//函数声明里有b和d
AO{
a:1,
b:function b(){}
c:undefined,
d:function d(){}
}
|
//此时四部曲结束,开始进入函数代值
AO{
a:3,
b:2,
c:0,
d:function d(){}
}
</script>
练习:
<script type = "text/javascript">
function test(a,b){
console.log(a); //function
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);
//function undefined 234 123 123 function
分析:
AO{
a:undefined,
b:undefined,
}
|
AO{
a:1, //这里虽然有两个形参,但只有一个形参,1只和a对应
b:undefined,
}
|
//函数声明里有a
AO{
a:function a(){},
b:undefined,
}
|
//此时四部曲结束,开始进入函数代值
AO{
a:123,
b:function(){}
}
</script>
预编译不止发生在函数体里,它还发生在全局。
(全局变量)GO === window
任何全局变量都是window上的属性
var a = 123;
function a (){
}
//console.log(window.a);
//console.log(a);所表示的是相同的
例题:
<script type = "text/javascript">
console.log(text);
function test(text){
console.log(text);
var test = 234;
console.log(text);
function test(){
}
}
test(1);
var test = 123;
//1 234 234
解题过程:
(1)GO{
test : undefined;
}
|
GO{
test : function(){
//...
}
}
console.log(text);
function test(text){
console.log(text);
var test = 234;
console.log(text);
function test(){
}
}
test(1);
var test = 123;
(2)test(1)之前都不看了,因为被提升了。
(3)然后开始执行函数,执行text(1),在执行的前一刻,先AO。
(4)
AO{
test : undefined ;
}
|
AO{
test : 1 ;
}
|
AO{
test : function(){},
}
//现在进入函数内部进行打印,GO、AO里面都有text,打印哪个呢?
//规则:先打印AO的text,如果AO没有,再向上找GO打印GO的text,GO和AO会形成一个链式关系。
|
//现在AO里面有,所以进入函数内部(局部变量),var test = 234提前,所以
AO{
test : 234{},
}
//再打印函数内部的两个打印语句,均为234.
</script>
例题:
<script type = "text/javascript">
var global = 100;
function fn(){
console.log(global);
}
fn();
//100
解题过程:
GO{
global : undefined,
fn : function(){...}
}
|
GO{
global : 100,
fn : function(){...}
}
|
var global = 100;
function fn(){
console.log(global);
}
//fn();对应的AO
AO{
} //里面啥都没有
|
//然后执行console.log(global);, //先去AO里面找,但是AO里面啥都没有,所以向上GO里面找,GO里面有,有global:100,打印100
fn();
</script>
例题:
<script type = "text/javascript">
global = 100;
function fn(){
console.log(global);
global = 200;
console.log(global);
var global = 300;
}
fn();
var global;
// undefined 200
解题过程:
GO {
global: undefined;
}
|
GO {
global: 100;
}
global = 100;
function fn(){
console.log(global);
global = 200;
console.log(global);
var global = 300;
}
AO{
global: undefined;
}
|
//此时进函数块里面走,
//第一步console.log(global);找AO,为undefined;第二步赋值为200,则console.log(global);此句打印为200.
fn();
var global;
</script>
例题:
<script type = "text/javascript">
function test(){
console.log(b);
if(a){
var b = 100;
}
c = 234;
console.log(c);
}
var a;
test();
a = 10;
console.log(c);
</script>
解题过程:
<script type = "text/javascript">
//GO全局变量{
// a:undefined //全局变量只有a
// c:234
//}
function test(){
console.log(b);//undefined 在AO里面找a,发现是undefined
if(a){
var b = 100;
}
console.log(a);//undefined 先在AO里面找a,没有,再去GO里面找a,发现是undefined
c = 234;
console.log(c);//先依次访问AO、GO,发现都没有,向上访问,234
}
var a;
test(); //在此处执行,所以在它之后加AO
//AO局部变量{
// 找形参,变量声明
// b:undefined
//}
a = 10;
console.log(c);
</script>
例题:
<script type = "text/javascript">
a = 100;
function demo(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 function
console.log(a); //10
}
var a;
demo(1);
console.log(a); //100
console.log(f); //123
</script>
// 2 undefined undefined 10 100 123
解题过程:
GO{
a:undefined //全局变量发现就只有一个a
demo:function(){}
f = 123
}
|
GO{
a:100
demo:function(){}
f = 123
}
AO{
e:undefined;
b:undefined;
c:undefined;
a:undefined;
}
|
AO{
e:1;
b:undefined;
c:undefined;
a:undefined;
}
|
AO{
e:function e(){},
b:undefined,
c:undefined,(function(){})//if里面不能声明function,这里我们当做老旧版本认为可以提出
a:undefined,
}
|
AO{
e:2,
b:undefined,
c:undefined,(function(){})
a:10,
}