js预编译:JavaScript是一种解释执行的语言,也就是说代码从上往下执行,但在执行的前一刻会有一个预编译过程。先看一下代码:
console.log(a);//undifined;
var a="a";
如果在赋值之后访问
var a="a"; console.log(a);//输出a
这是因为在js当中,声明和赋值分两步完成,在代码执行的时候,先将变量申明提前,然后在执行的时候将变量的值赋值给他。
dome();//5 function dome() { console.log(5); }
同样的,在预编译的时候函数申明也会提前,所以以上代码能正确运行。那函数申明和变量申明在预编译提前的时候有没有哪个优先提到最前面呢?运行以下代码:
function a() { console.log("456"); } var a=123; a();//a is not a function
以上代码本来打算执行a函数,却显示a不是一个函数,原因是后面的变量名和函数a相同,将其覆盖了,也就是说在预编译函数申明和变量申明在提前的时候,函数总是提在逻辑的最前面。
如果一个函数形参、函数名、变量名都相同的情况下,执行过程是样的呢?
function fn(a)
{
console.log(a);//function a(){}
var a="123";
console.log(a);//123
function a()
{
}
console.log(a);//123
}
fn(1);
这段代码的执行可以会产生一个活动对象,我们简称AO,里面存放了变量和他的值,解析过程分四步完成:
1、找实参和形参变量
2、将形参和实参作为AO属性名,值为undifined
3、将实参和形参统一,
4、在函数体里面找函数申明,值赋予函数体。
所以第一个console.log最后输出为function a(),每次执行的时候都是改变该活动对象的里面的值,第二次执行到var a=123,由于变量申明提前,只需要执行赋值操作,及将AO里的a的值变为123,后面由于function a()在声明的时候已经提前,所以console.log依然输出123。
在js当中代码未经申明直接赋值,也能访问:
任何变量未经申明就赋值,此变量为全局变量公有吗,及归window所有。上面代码等价于:a="123"; console.log(a);//123
window.a="123"; window { a:"123" }