javascript是单线程的解释性语言,
单线程就是先执行完一个,再执行另一个;
解释性语言就是先翻译一行,再执行一行,先翻译一行,再执行一行
语法分析
扫描一遍是否有低级语法错误
词法分析(预编译阶段) 例子
1 2 3 4 5 6 7 8 9 10 11 function foo (a) { console .log (a) var a = 123 console .log (a) function a () {} console .log (a) var b = function ( ) {} console .log (b) function d () {} } foo (1 )
创建 AO 对象
找形参和变量声明
将形参和变量名作为 AO 属性名,值为 undefined
1 2 3 4 AO { a : undefined , b : undefined }
形参和实参统一 1 2 3 4 AO { a : 1 , b : undefined }
函数体里找函数声明,赋值函数体 1 2 3 4 5 AO { a : [Function a], b : undefined , d : [Function d] }
AO 创建完成后执行函数(执行阶段) 1 2 3 4 5 6 7 8 9 10 11 12 function foo (a) { console .log (a) var a = 123 console .log (a) function a () {} console .log (a) var b = function ( ) {} console .log (b) function d () {} console .log (d) } foo (1 )
解释
创建 AO,并声明形参 -> 变量 -> 函数
形参 a = undefined,变量 a = undefined,变量 b = undefined
函数 foo 声明并赋值函数体
函数 a 声明并赋值函数体
函数 d 声明并赋值函数体
执行并赋值
形参 a = 1, 函数 a 赋值已提前,输出 a => [Function a]
变量 a = 123,输出 a => 123
函数 a 赋值函数体 已被提前,还是 输出 a => 123
变量 b 赋值为函数体,输出 b => [Function b]
函数 d 赋值已提前,输出 d => [Function d]
例子 1 2 3 4 5 6 7 8 9 var a = "10" function foo (a) { console .log (a) var a = 20 } foo () foo (123 )
总结
先声明形参和变量,再声明函数
变量提升 (声明和赋值都提前)1 2 function foo () {}foo ()