1
语法分析 →
2
预编译 →
3
解释执行
第一步、初步扫描,查看简单的语法错误;
例
function test(){
console.log(‘a’);
}
test();
上面能执行
例
test();
function test(){
console.log(‘a’);
}
也能执行,因为有预编译的存在
例
var a = 123;
console.log(a);
答案
123
例
console.log(a);
var a = 123;
答案
undefined
例
只写
console.log(a);
就会报错
函数声明整体提升
:函数不管写到哪里,都会被提到逻辑的最前面。所以不管在哪
里调用,本质上都是在后面调用
变量
声明提升
:把
var a
提升到最前面
var a = 123;
这是变量声明再赋值。
变量
声明提升是把他拆分成
var a; a = 123;
然后把
var a
提升到最前面
上面这两句话没办法解决下面
例
子的问题
例
function a(a){
var a = 234;
var a = function(){
}
a();
var a =123;
1.imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为
全局对象(就是 window)所有。
全局对象是
window
例
window.a = 10;
例
a = 10; ===> windows.a = 10;
eg: var a = b = 123;
2.一切声明的全局变量,全是 window 的属性。
例
var a = 123; ===> window.a = 123;
window
就是全局的域
如果在全局变量在
var a = 123
;那么就会返回到
window
例
var a = 123
console.log(a) ===> window.a
例
var a = b = 234;
是把
234
的值赋给
b
,在把
b
的值赋给
a
例
function test(){
var a = b = 123;
}
test()
写
test()
代表执行
test
,赋值是自右向左的,上面先把
123
赋给
b
的时候,
b
未经声明,
然后再声明
a
,再
b
的值赋给
a
,导致
b
未经声明,所以
b
归
window
所有
访问
window.a
是
undefined
,
访问
window.b
是
123;
例
function test(){
var b = 123;
}
test();
console.log(window.b); // undefined
window
就是全局。
例
var a = 123;
console.log(a);
→
console.log(window.a);
例
var a = 123;
var b = 234;
var c = 345;
window{
a : 123,
b : 234,
c : 345
}
如果
var a
对应会有
window.a。
第二步、预编译js代码:
预编译(解决执行顺序问题) :
1.创建 AO 对象 Activation Object(执行期上下文,作用是理解的作用域,函数产生
的执行空间库)
2.找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined
相当于 AO{
a : undefined,
b : undefined
}
3.将实参值和形参统一(把实参值传到形参里)
4.在函数体里面找函数声明,值赋予函数体
(先看自己的 AO,再看全局的 GO);
例
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 a(){}
//
123
//
123
//
function (){}
这个
例
子的形参是(
a
),变量声明也是
a
上面的
例
子按四部曲变化如下
:
第一步:创建AO;
第二步:找形参和变量声明,将变量和形参(
a
)名作为
AO
属性名,值为
undefined
,
AO{
a : undefined,
b : undefined,
}
第三步:(把实参值传到形参里)
AO{
a : 1,
b : undefined,
}
===>
function a () {}
和
function d () {}
都是函数声明,但是
var b = function (){}
不是。
AO{
a : function a () {},
b : undefined,
d : function d () {}
}
第四步:
执行第一行
console.log(a);
时,用的是
AO{
a : function a () {},
b : undefined,
d : function d () {}
}
执行
var a =123;
改变的是
AO{
a : 123,
b : undefined,
d : function d () {}
}
在
b = function (){}
时
AO{
a : 123,
b : function () {},
d : function d () {}
}
预编译发生在函数执行的前一刻;