JavaScript入门(五)-预编译(总+例题详解)
一、预编译前置知识-全局变量
- imply global 暗示全局变量:即任何变量,未经声明就赋值,此变量为全局对象所有。
//以下三种方式效果相同
a = 10;
window.a = 10;
window {
a : 10;
}
function test() {
var b = a =10;//此时a声明就赋值,为全局变量,b不是
}
- 一切的声明的全局变量,全是windows的属性,
var a = 10;//效果等价1
var b = 20;
//在全局范围内访问a的话就是相当于访问window.a,b同理。
window 全局变量的对象,window即为全局变量的域。
二、预编译规则
预编译:在代码逐行执行前,先进行的编译,在执行中不再重复执行。
时间 :在函数被执行之前进行
先上,简单口诀
- 函数声明整体提升
- 变量 声明提升
1、预编译-函数内
示例函数
//预编译发生在函数执行的前一刻
//以此为例,分析结果
function test(a, b){
console.log(a);
console.log(b);
var b = 234;
console.log(b);
a = 123;
console.log(a);
function a (){}
var a;
b =234;
var b = function(){}
console.log(a);
console.log(b);
}
test(1);
步骤:
-
- 创建AO对象 Activation Object (执行上下文)
-
- 找形参和变量声明,将变量声明和形参的名作为AO的属性名,值为undefined。
-
- 将实参和形参相统一
-
- 找函数体内的函数声明,将函数名作为属性名,将函数作为属性值。
以下为步骤解释
// 第一步
AO {
}
//第二步
AO {
a : undefined,
b : undefined,
}
//第三步,test(1)这里只有a被有实参
AO {
a : 1,
b : undefined,
}
//第四步,b为表达式,并不是声明b对象的函数体,上述代码中是赋值。
AO {
a : function a(){},
b : undefined,
}
执行的结果(在执行过程中相同的会覆盖):
function a(){}
undefined
234
123
function (){}
2、预编译 -全局
步骤:
-
- 创建GO对象 Global Object (执行上下文)
-
- 找变量声明,将变量声明为GO的属性名,值为undefined。
-
- 全局内的函数声明,将函数名作为属性名,将函数作为属性值。
console.log(window.test);
function test (){
var a = b = 123;
}
test(1);
console.log(b);
console.log(window.test);
//1.创建GO变量
//2.
/*
GO {
b : undefined ,未声明的变量定位全局变量,如前文介绍
}
*/
// 3.
/* GO
b : undefined
test : test (){
var a = b = 123;
}
}
*/
//最后改片段的执行结果(控制台)为
/*
ƒ test (){
var a = b = 123;
}
123
ƒ test (){
var a = b = 123;
}
*/
三、预编译-总-例题+详细讲解
总体来看,为从外层到内层的过程。先最外层预编译,然后外层预编译完成后,执行外层的的代码 (预编译过的不再执行),当将要执行到某个函数时,会进行函数内的预编译(也正如上述所说,预编译在函数将要执行之前),这也使得其进入内层。
例题代码,分析结果
a = 100;
function demo(e) {
function e() {}
arguments [0] = 2;
console.log(e);
if(a){
var b = 123;
}
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);
为了使其过程明了,在此分了以下几步
Step1: 先进行全局的预编译,
GO {
a : undefined,
e : function demo(e) {...}
}
Step2: 之后逐步剩下语句
依次为 a = 100;
再者为 demo(1);----->注意!在调用函数之前进行 预编译(函数内)
Step3: 在函数内进行预编译
注意: arguments[0]和e的值映射相同
注意: a在AO 和GO 的范围的不同
AO {
e : function e() {},
b : undefined,
a : undefined,
c : undefined,
}
GO {
a : 100,
e : function e() {...}
f : undefined,
}
Step4: 执行函数内语句后
注意:if语句内语句不执行(条件为假,a为undefined)
此时控制台输出为:
2
undefined
undefined
10
AO {
e : 2;
b : undefined,
a : 10,
c : undefined,
}
GO {
a : 100,
e : function e(){},
f : 123
}
Step5 : 函数执行完毕,继续执行
console.log(a);
console.log(f);
此时,控制台输出为
2
undefined
undefined
10
100
123
四、其他小题目
以下为几个例子,可以彰显出这个规则
1.
global = 100;
function fn() {
console.log(global);
global = 200;
console.log(global);
var global = 300;
}
fn();
var global;
在浏览器的控制台粘贴这段代码,即可知道运行结果
undefined
200
2.
function bar() {
return foo;
function foo() {
}
var foo = 11;
}
console.log(bar());
控制台输出:
function foo() {
}
3.
console.log(bar());
function bar() {
foo = 10;
function foo() {
}
var foo = 11;
return foo;
}
控制台输出:11
以上,此为本人学习过程中的笔记,可能因为能力不足存在一些不足,还请大家多多包涵和给予建议,共同进步。如有问题,敬请私信。