目录
一:预编译前奏
二:函数体系内的预编译
三:全局的预编译
四:例题
赋值一定是自右向左的,所以是先把123赋给b,再把b赋给a,b是未经声明的,所以全局能访问到b,a是局部变量所以访问不到
二:函数体系内的预编译
函数执行的前一刻生成AO,GO是一开始就有的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- //js运行三部曲
一:语法分析
二:预编译:发生在函数执行的前一刻
预编译前奏: window 就是全局的域
1:imply global:暗示全局变量,即任何变量,如果变量未经声明就赋值,此变量就归全局对象所有,全局对象是window 如: a=10; ==> window.a=10;
2:一切声明的全局变量(在函数中则不是全局变量),全是window的属性。注意:只有全局的才能归window所有,局部的不行
var a=123;==>window.a=123;
预编译四部曲:预编译发生在函数执行的前一刻
1:创建AO对象 Activation Object(执行期上下文) AO{}
2:找函数里的形参和变量声明,将变量和形参名作为AO属性名,值为undefined AO{
例1:
a:undefined
b:undefined
}
3:将实参值和形参统一 形参a变为1
4:在函数体里面找函数声明。值赋予函数体 a和d都是函数声明 b是函数表达式
以上四个步骤以例一为例
1:创建AO作用域
AO{
}
2:AO{
a:undefined
b:undefined
}
3:AO{
a:1;
b:undefined
}
4:AO{
a: function a(){}
b:undefined
d: function d(){}
}
//函数声明是 funtion b(){}
//函数表达式是 var b=funtion (){}
//函数声明整体提升: 函数声明不管写到哪里,系统总是会把函数提到逻辑最前面
//变量 声明提升 :赋值不提升,var a会提到前面(预编译执行),就是预编译过程中var a的声明已经看过了。
但是赋值是在解释执行的时候赋值的。解释执行时不再看预编译的内容
三:解释执行 -->
<script type="text/javascript">
//解释执行代码
//例1:
function fn(a){
console.log(a);//输出function a(){}
var a=123;
//AO{
// a:123
// b:undefined,
// d:function d(){}
// }
console.log(a);//输出123
function a(){}//预编译已经看过的地方不再看了
console.log(a);//输出123
var b=function (){}//预编译已经看过的地方不再看了
//AO{
// a:123
// b:function (){}
// d:function d(){}
// }
console.log(b);//输出function (){}
function d(){}
}
fn(1);
//例2:
function test(a,b){
console.log(a);//1
c=0;
var c;
a=3;
b=2;
console.log(b);//2
function b(){}
function d(){}
console.log(b);//2
}
test(1);
//第二步
// AO{
// a:undefined
// b:undefined
// c:undefined
// }
//第三,四步:
// AO{
// a:1
// b:function b(){}
// c:undefined
// d:function d(){}
// }
// 例3:
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);
</script>
</head>
<body>
</body>
</html>
三:全局的预编译
未经声明的变量都会提升到全局变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!--
例1:生成了一个GO对象Global Object
除了没有实参形参,其他步骤和函数体系内预编译过程是相同的
GO{
a:undefined->function(){}
}
GO===window
-->
<!-- 例1:生成了一个GO对象Global -->
<script>
var a=123;
function a(){}
console.log(a);
</script>
<!-- //例2: -->
<script>
// GO{
// b:123;
// }
function test(){
var a=b=123;//没有声明b,从右至左顺序执行的
console.log(b);
}
test();
// AO{
// a:undefined
// }
</script>
<!-- 例3: -->
<script>
// GO{
// test:undefined->函数体function test(test){...}
// }
console.log(test);//输出function test(test){...}
function test(test){//提升了不看了,下一步执行函数再创建AO再执行这里
console.log(test);//输出function test(){}
var test=234;
console.log(test);//输出234
function test(){}
}
test(1);
var test=123;
// AO{
// test:undefined->1->function test(){}
// }
</script>
<!-- 例4: -->
<script>
// GO{
// global:undefined GO{
// global:100
// -> fn:function fn(){...}
// } }
var global=100;
function fn(){
console.log(global);//先上AO上找,没有,再去GO上找
}
fn();
// AO{
// 空的
// }
</script>
<!--例5 -->
<script>
// GO{
// global:undefined
// fn:fn(){}
// }
global=100;
function fn(){
console.log(global);//undefined 先找自己AO的
global=200;
console.log(global);//200
var global=300;
}
fn();
var global;
// AO{
// global:undefined
// }
</script>
<!-- 例6 -->
<script>
// GO{
// a:undefined
// test:function test(){...}
// c:234
// }
function test(){
console.log(b);//undefined error
if(a){ //a=undefined
var b=100;
}
console.log(b);//undefined
c=234;//AO里面没c,添加到GO里去
console.log(c);//234
}
var a;
test();//调用函数时开始创建AO
// AO{
// b:undefined 不用管if if里的判断不管怎样,都会变量提升
// }
a=10;
console.log(c);//234
</script>
<!-- 百度笔试题1 -->
<script>
// GO{
// bar:function bar(){...}
// }
function bar (){
return foo;//相当于console.log(foo)
foo=10;
function foo(){
}
var foo=11;
}
console.log(bar());//foo(){...}
// AO{
// foo:foo(){}
// }
</script>
<!-- 百度笔试题2 -->
<script>
// GO{
// bar:function bar(){...}
// }
console.log(bar());
function bar()
{
foo=10;
function foo(){
}
var foo=11;
return foo;//相当于console.log(foo)
}
// AO{
// foo:foo(){}
// }
</script>
<!-- 例7 -->
<script>
console.log(b);//undefined b是函数表达式,不是函数
var b = function () {}
</script>
<!-- 例8 -->
<script>
// GO{
// a:undefined->100
// demo:demo(){...}
// f:123
// }
a=100;//a:undefined->100
function demo(e){
function e(){}
arguments[0]=2;//e=2 arguments控制实参,实参第一位改成2
console.log(e);//输出2
if(a){//a=undefined 不执行if语句
var b=123;
function c(){//if里面不能声明function,在这里只作为练习
}
}
var c;
a=10;
var a;
console.log(b);//输出undefined
f=123;//AO里面没f,添加到GO里去
console.log(c);//输出undefined
console.log(a);//输出10
}
var a;
demo(1);
// AO{
// e:undefined->1->function e(){}->2
// b:undefined
// c:function c()/undefined
// a:undefined->10
// }
console.log(a);//输出100, 全局变量看GO里的
console.log(f);//输出123
</script>
</head>
<body>
</body>
</html>
四:例题
1.
<script>
/*
GO{
a:undefined=>100
demo:function(){}
f:un=>123
}
*/
a = 100;
function demo(e) {
function e() {}
arguments[0] = 2; //形参列表第一个 和实参相映射 所以e变成2
console.log(e); //2
if (a) {//预编译时不看if里的条件,直接将if里的变量放进AO,执行时看if里的条件是否满足,由于a=undefined,所以不执行里面的语句
var b = 123;
function c() {}
}
var c;
a = 10;
var a;
console.log(b); //un
f = 123;//AO没有,放进GO里
console.log(c); //function 由于新语法 函数不能定义再if语句里,所以这里实际打印出来的值时undefined
console.log(a); //10
}
var a;
demo(1);
console.log(a); //全局里的a 100
console.log(f); //123
/*
AO{
e:un=>1=>function=>2
b:un
c:function
a:un=>10
}
*/
</script>
2.
<script>
function print(){
console.log(foo);//undefined
var foo=2;
console.log(foo);//2
console.log(hello);//报错
}
print()
</script>
版权声明:本文为x1037490413原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。